home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2001 May / may_2001.iso / intercd / root / Multimedia / ^DivX_Article / virtualdub / VirtualDub-source-1_4d / Disasm.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-03-20  |  62.3 KB  |  2,039 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2001 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <string.h>
  19. #include <stdio.h>
  20. #include <crtdbg.h>
  21.  
  22. #include <windows.h>
  23.  
  24. #include "resource.h"
  25. #include "disasm.h"
  26.  
  27. extern HINSTANCE g_hInst;
  28.  
  29. #define MAX_INSTRUCTIONS (1024)
  30.  
  31. // WARNING: This is called from crash-time conditions!  No malloc() or new!!!
  32.  
  33. #define malloc not_allowed_here
  34. #define new not_allowed_here
  35.  
  36. // Also, we keep as much of our initialized data as possible as const.  That way,
  37. // it is in a write-locked code segment, which can't be overwritten.
  38.  
  39. CodeDisassemblyWindow::CodeDisassemblyWindow(void *_code, long _length, void *_rbaseptr, void *_abaseptr)
  40. : code(_code)
  41. , rbase(_rbaseptr)
  42. , abase(_abaseptr)
  43. , length(_length)
  44. , pFault(0)
  45. {
  46. //    lbents = new lbent[MAX_INSTRUCTIONS];
  47.     lbents = (lbent *)VirtualAlloc(NULL, sizeof(lbent)*MAX_INSTRUCTIONS, MEM_COMMIT, PAGE_READWRITE);
  48.  
  49.     parse();
  50.  
  51.     hFontMono = CreateFont(
  52.             10,                // nHeight
  53.             0,                // nWidth
  54.             0,                // nEscapement
  55.             0,                // nOrientation
  56.             FW_DONTCARE,    // fnWeight
  57.             FALSE,            // fdwItalic
  58.             FALSE,            // fdwUnderline
  59.             FALSE,            // fdwStrikeOut
  60.             ANSI_CHARSET,    // fdwCharSet
  61.             OUT_DEFAULT_PRECIS,        // fdwOutputPrecision
  62.             CLIP_DEFAULT_PRECIS,    // fdwClipPrecision
  63.             DEFAULT_QUALITY,        // fdwQuality
  64.             DEFAULT_PITCH | FF_DONTCARE,    // fdwPitchAndFamily
  65.             "Lucida Console"
  66.             );
  67.  
  68.     if (!hFontMono) hFontMono = (HFONT)GetStockObject(ANSI_FIXED_FONT);
  69.  
  70. }
  71.  
  72. CodeDisassemblyWindow::~CodeDisassemblyWindow() {
  73.  
  74.     if (hFontMono) DeleteObject(hFontMono);
  75.  
  76.     if (lbents)
  77.         VirtualFree(lbents, 0, MEM_RELEASE);
  78. }
  79.  
  80. /////////////////////////////////////////////////////////////////////////
  81.  
  82. #define ADDR1(am) ((am)<<6)
  83. #define ADDR2(am1,am2) ((am1) | ((am2)<<6))
  84. #define ADDR3(am1,am2,am3) ((am1) | ((am2)<<6) | ((am3)<<6))
  85. #define MOD(t) ((t)<<18)
  86. #define TYPE(t) ((t)<<20)
  87. #define GROUP(grp) ((grp)<<26)
  88.  
  89. #define GETADDR1(fl) ((fl) & 63)
  90. #define GETADDR2(fl) (((fl)>>6) & 63)
  91. #define GETADDR3(fl) (((fl)>>12) & 63)
  92. #define GETMOD(fl) (((fl)>>18) & 3)
  93. #define GETTYPE(fl) (((fl)>>20) & 63)
  94. #define GETGROUP(fl) (((fl)>>26) & 63)
  95.  
  96. enum {
  97.     ADDR0_MASK        =0x0000003fL,
  98.     ADDR1_MASK        =0x00000fc0L,
  99.     ADDR2_MASK        =0x0003f000L,
  100.     MOD16_MASK        =0x000c0000L,
  101.     TYPE_MASK        =0x03f00000L,
  102.     GROUP_MASK        =0xfc000000L,
  103.  
  104.     ADDR_AL            =1,
  105.     ADDR_CL,
  106.     ADDR_DX,
  107.     ADDR_EAX,
  108.  
  109.     ADDR_CS,
  110.     ADDR_DS,
  111.     ADDR_SS,
  112.     ADDR_ES,
  113.     ADDR_FS,
  114.     ADDR_GS,
  115.  
  116.     ADDR_1,
  117.     ADDR_Ap,    // direct address
  118.     ADDR_Cd,    // reg of mod r/m selects control register
  119.     ADDR_Dd,    // reg of mod r/m selects debug register
  120.     ADDR_Eb,    // mod r/m specifies register or address
  121.     ADDR_Ed,
  122.     ADDR_Ep,
  123.     ADDR_Eq,
  124.     ADDR_Ev,
  125.     ADDR_Ex,
  126.     ADDR_Ew,
  127.     ADDR_Gb,    // reg of mod r/m selects register or memory operand
  128.     ADDR_Gv,
  129.     ADDR_Gw,
  130.     ADDR_Ib,    // immediate
  131.     ADDR_Ib2,
  132.     ADDR_Iv,
  133.     ADDR_Iw,
  134.     ADDR_Jb,    // relative offset
  135.     ADDR_Jv,
  136.     ADDR_M,        // reg of mod r/m selects memory
  137.     ADDR_Ma,
  138.     ADDR_Mp,
  139.     ADDR_Ob,    // offset coded directly
  140.     ADDR_Ow,
  141.     ADDR_Od,
  142.     ADDR_Oq,
  143.     ADDR_Ov,
  144.     ADDR_Pd,    // reg of mod r/m selects packed MMX register
  145.     ADDR_Pq,
  146.     ADDR_Pq2,    // INTEL DOCERR: p-shift instrs in group A have reg in bits 0-3 of mod r/m
  147.     ADDR_Qd,    // mod r/m byte selects MMX register or memory operand
  148.     ADDR_Qq,
  149.     ADDR_Rd,    // mod field of mod r/m selects register only
  150.     ADDR_Sw,    // reg of mod r/m selects segment register
  151.     ADDR_Xb,    // ds:[e]si memory operand
  152.     ADDR_Xv,
  153.     ADDR_Yb,    // es:[e]di memory operand
  154.     ADDR_Yv,
  155.  
  156.     ADDR_Idep        =60,
  157.     ADDR_Ibs        =61,
  158.     ADDR_reg8        =62,
  159.     ADDR_reg32        =63,
  160.  
  161.     TYPE_cs_override            =1,
  162.     TYPE_ds_override            =2,
  163.     TYPE_ss_override            =3,
  164.     TYPE_es_override            =4,
  165.     TYPE_fs_override            =5,
  166.     TYPE_gs_override            =6,
  167.     TYPE_operand_size_override    =7,
  168.     TYPE_address_size_override    =8,
  169.     TYPE_0f                        =9,
  170.     TYPE_prefix                    =10,
  171.  
  172.     MOD16_take_d_off            =1,
  173.     MOD16_d_to_w                =2,
  174.     MOD16_dq_to_wd                =3,
  175. };
  176.  
  177. #define SPECIAL_3DNOW        (0xFFFFFF00)
  178.  
  179. static const char op_aaa        []="aaa";
  180. static const char op_aad        []="aad";
  181. static const char op_aam        []="aam";
  182. static const char op_aas        []="aas";
  183. static const char op_adc        []="adc";
  184. static const char op_add        []="add";
  185. static const char op_and        []="and";
  186. static const char op_arpl        []="arpl";
  187. static const char op_bound        []="bound";
  188. static const char op_bsf        []="bsf";
  189. static const char op_bsr        []="bsr";
  190. static const char op_bswap        []="bswap";
  191. static const char op_bt            []="bt";
  192. static const char op_btc        []="btc";
  193. static const char op_btr        []="btr";
  194. static const char op_bts        []="bts";
  195. static const char op_call        []="call";
  196. static const char op_cbw        []="cbw";
  197. static const char op_cdq        []="cdq";
  198. static const char op_clc        []="clc";
  199. static const char op_cld        []="cld";
  200. static const char op_cli        []="cli";
  201. static const char op_clts        []="clts";
  202. static const char op_cmc        []="cmc";
  203.  
  204. static const char op_cmovc        []="cmovc";
  205. static const char op_cmovnc        []="cmovnc";
  206. static const char op_cmovp        []="cmovp";
  207. static const char op_cmovnp        []="cmovnp";
  208. static const char op_cmovs        []="cmovs";
  209. static const char op_cmovns        []="cmovns";
  210. static const char op_cmovl        []="cmovl";
  211. static const char op_cmovle        []="cmovle";
  212. static const char op_cmovg        []="cmovg";
  213. static const char op_cmovge        []="cmovge";
  214. static const char op_cmovo        []="cmovo";
  215. static const char op_cmovno        []="cmovno";
  216. static const char op_cmovz        []="cmovz";
  217. static const char op_cmovnz        []="cmovnz";
  218. static const char op_cmova        []="cmova";
  219. static const char op_cmovbe        []="cmovbe";
  220.  
  221. static const char op_cmp        []="cmp";
  222. static const char op_cmpsb        []="cmpsb";
  223. static const char op_cmpsd        []="cmpsd";
  224. static const char op_cmpxchg    []="cmpxchg";
  225. static const char op_cmpxchg8b    []="cmpxchg8b";
  226. static const char op_cpuid        []="cpuid";
  227. static const char op_daa        []="daa";
  228. static const char op_das        []="das";
  229. static const char op_dec        []="dec";
  230. static const char op_div        []="div";
  231. static const char op_emms        []="emms";
  232. static const char op_enter        []="enter";
  233.  
  234. static const char op_fadd        []="fadd";
  235. static const char op_faddp        []="faddp";
  236. static const char op_fbld        []="fbld";
  237. static const char op_fbstp        []="fbstp";
  238. static const char op_fcmovb        []="fcmovb";
  239. static const char op_fcmovbe    []="fcmovbe";
  240. static const char op_fcmove        []="fcmove";
  241. static const char op_fcmovnb    []="fcmovnb";
  242. static const char op_fcmovnbe    []="fcmovnbe";
  243. static const char op_fcmovne    []="fcmovne";
  244. static const char op_fcmovnu    []="fcmovnu";
  245. static const char op_fcmovu        []="fcmovu";
  246. static const char op_fcom        []="fcom";
  247. static const char op_fcomi        []="fcomi";
  248. static const char op_fcomip        []="fcomip";
  249. static const char op_fcomp        []="fcomp";
  250. static const char op_fdiv        []="fdiv";
  251. static const char op_fdivp        []="fdivp";
  252. static const char op_fdivr        []="fdivr";
  253. static const char op_fdivrp        []="fdivrp";
  254. static const char op_ffree        []="ffree";
  255. static const char op_fiadd        []="fiadd";
  256. static const char op_ficom        []="ficom";
  257. static const char op_ficomp        []="ficomp";
  258. static const char op_fidiv        []="fidiv";
  259. static const char op_fidivr        []="fidivr";
  260. static const char op_fild        []="fild";
  261. static const char op_fimul        []="fimul";
  262. static const char op_fist        []="fist";
  263. static const char op_fistp        []="fistp";
  264. static const char op_fisub        []="fisub";
  265. static const char op_fisubr        []="fisubr";
  266. static const char op_fld        []="fld";
  267. static const char op_fldcw        []="fldcw";
  268. static const char op_fldenv        []="fldenv";
  269. static const char op_fmul        []="fmul";
  270. static const char op_fmulp        []="fmulp";
  271. static const char op_frstor        []="frstor";
  272. static const char op_fsave        []="fsave";
  273. static const char op_fst        []="fst";
  274. static const char op_fstcw        []="fstcw";
  275. static const char op_fstenv        []="fstenv";
  276. static const char op_fstp        []="fstp";
  277. static const char op_fstsw        []="fstsw";
  278. static const char op_fsub        []="fsub";
  279. static const char op_fsubp        []="fsubp";
  280. static const char op_fsubr        []="fsubr";
  281. static const char op_fsubrp        []="fsubrp";
  282. static const char op_fucom        []="fucom";
  283. static const char op_fucomi        []="fucomi";
  284. static const char op_fucomip    []="fucomip";
  285. static const char op_fucomp        []="fucomp";
  286. static const char op_fxch        []="fxch";
  287.  
  288. static const char op_hlt        []="hlt";
  289. static const char op_idiv        []="idiv";
  290. static const char op_imul        []="imul";
  291. static const char op_inc        []="inc";
  292. static const char op_in            []="in";
  293. static const char op_int        []="int";
  294. static const char op_int3        []="int\t3";
  295. static const char op_into        []="into";
  296. static const char op_insb        []="insb";
  297. static const char op_insd        []="insd";
  298. static const char op_invalid    []="invalid";
  299. static const char op_invd        []="invd";
  300. static const char op_invlpg        []="invlpg";
  301. static const char op_iret        []="iret";
  302.  
  303. static const char op_jc            []="jc";
  304. static const char op_jnc        []="jnc";
  305. static const char op_jp            []="jp";
  306. static const char op_jnp        []="jnp";
  307. static const char op_js            []="js";
  308. static const char op_jns        []="jns";
  309. static const char op_jl            []="jl";
  310. static const char op_jle        []="jle";
  311. static const char op_jg            []="jg";
  312. static const char op_jge        []="jge";
  313. static const char op_jo            []="jo";
  314. static const char op_jno        []="jno";
  315. static const char op_jz            []="jz";
  316. static const char op_jnz        []="jnz";
  317. static const char op_ja            []="ja";
  318. static const char op_jbe        []="jbe";
  319.  
  320. static const char op_jecxz        []="jecxz";
  321. static const char op_jmp        []="jmp";
  322. static const char op_lahf        []="lahf";
  323. static const char op_lar        []="lar";
  324. static const char op_lds        []="lds";
  325. static const char op_lea        []="lea";
  326. static const char op_leave        []="leave";
  327. static const char op_les        []="les";
  328. static const char op_lfs        []="lfs";
  329. static const char op_lgdt        []="lgdt";
  330. static const char op_lgs        []="lgs";
  331. static const char op_lidt        []="lidt";
  332. static const char op_lldt        []="lldt";
  333. static const char op_lmsw        []="lmsw";
  334. static const char op_lock        []="lock";
  335. static const char op_lodsb        []="lodsb";
  336. static const char op_lodsd        []="lodsd";
  337. static const char op_loop        []="loop";
  338. static const char op_loope        []="loope";
  339. static const char op_loopn        []="loopn";
  340. static const char op_lsl        []="lsl";
  341. static const char op_lss        []="lss";
  342. static const char op_ltr        []="ltr";
  343. static const char op_mov        []="mov";
  344. static const char op_movd        []="movd";
  345. static const char op_movq        []="movq";
  346. static const char op_movsb        []="movsb";
  347. static const char op_movsd        []="movsd";
  348. static const char op_movsx        []="movsx";
  349. static const char op_movzx        []="movzx";
  350. static const char op_mul        []="mul";
  351. static const char op_neg        []="neg";
  352. static const char op_nop        []="nop";
  353. static const char op_not        []="not";
  354. static const char op_or            []="or";
  355. static const char op_out        []="out";
  356. static const char op_outsb        []="outsb";
  357. static const char op_outsd        []="outsd";
  358. static const char op_packssdw    []="packssdw";
  359. static const char op_packsswb    []="packsswb";
  360. static const char op_packusdw    []="packusdw";
  361. static const char op_paddb        []="paddb";
  362. static const char op_paddd        []="paddd";
  363. static const char op_paddw        []="paddw";
  364. static const char op_paddsb        []="paddsb";
  365. static const char op_paddsd        []="paddsd";
  366. static const char op_paddsw        []="paddsw";
  367. static const char op_paddusb    []="paddusb";
  368. static const char op_paddusd    []="paddusd";
  369. static const char op_paddusw    []="paddusw";
  370. static const char op_pand        []="pand";
  371. static const char op_pandn        []="pandn";
  372. static const char op_pavgusb    []="pavgusb";
  373. static const char op_pcmpeqb    []="pcmpeqb";
  374. static const char op_pcmpeqd    []="pcmpeqd";
  375. static const char op_pcmpeqw    []="pcmpeqw";
  376. static const char op_pcmpgtb    []="pcmpgtb";
  377. static const char op_pcmpgtd    []="pcmpgtd";
  378. static const char op_pcmpgtw    []="pcmpgtw";
  379.  
  380. static const char op_pmaddwd    []="pmaddwd";
  381. static const char op_pmulhw        []="pmulhw";
  382. static const char op_pmullw        []="pmullw";
  383. static const char op_pop        []="pop";
  384. static const char op_popad        []="popad";
  385. static const char op_popfd        []="popfd";
  386. static const char op_por        []="por";
  387. static const char op_pslld        []="pslld";
  388. static const char op_psllq        []="psllq";
  389. static const char op_psllw        []="psllw";
  390. static const char op_psrad        []="psrad";
  391. static const char op_psraw        []="psraw";
  392. static const char op_psrld        []="psrld";
  393. static const char op_psrlq        []="psrlq";
  394. static const char op_psrlw        []="psrlw";
  395. static const char op_psubb        []="psubb";
  396. static const char op_psubd        []="psubd";
  397. static const char op_psubw        []="psubw";
  398. static const char op_psubsb        []="psubsb";
  399. static const char op_psubsd        []="psubsd";
  400. static const char op_psubsw        []="psubsw";
  401. static const char op_psubusb    []="psubusb";
  402. static const char op_psubusd    []="psubusd";
  403. static const char op_psubusw    []="psubusw";
  404. static const char op_punpckhbw    []="punpckhbw";
  405. static const char op_punpckhdq    []="punpckhdq";
  406. static const char op_punpckhwd    []="punpckhwd";
  407. static const char op_punpcklbw    []="punpcklbw";
  408. static const char op_punpckldq    []="punpckldq";
  409. static const char op_punpcklwd    []="punpcklwd";
  410. static const char op_push        []="push";
  411. static const char op_pushad        []="pushad";
  412. static const char op_pushfd        []="pushfd";
  413. static const char op_pxor        []="pxor";
  414. static const char op_rcl        []="rcl";
  415. static const char op_rcr        []="rcr";
  416. static const char op_rdmsr        []="rdmsr";
  417. static const char op_rdpmc        []="rdpmc";
  418. static const char op_rdtsc        []="rdtsc";
  419. static const char op_rep        []="rep";
  420. static const char op_repne        []="repne";
  421. static const char op_ret        []="ret";
  422. static const char op_retf        []="retf";
  423. static const char op_rol        []="rol";
  424. static const char op_ror        []="ror";
  425. static const char op_rsm        []="rsm";
  426. static const char op_sahf        []="sahf";
  427. static const char op_sar        []="sar";
  428. static const char op_sbb        []="sbb";
  429. static const char op_scasb        []="scasb";
  430. static const char op_scasd        []="scasd";
  431.  
  432. static const char op_setc    []="setc";
  433. static const char op_setnc    []="setnc";
  434. static const char op_setp    []="setp";
  435. static const char op_setnp    []="setnp";
  436. static const char op_sets    []="sets";
  437. static const char op_setns    []="setns";
  438. static const char op_setl    []="setl";
  439. static const char op_setle    []="setle";
  440. static const char op_setg    []="setg";
  441. static const char op_setge    []="setge";
  442. static const char op_seto    []="seto";
  443. static const char op_setno    []="setno";
  444. static const char op_setz    []="setz";
  445. static const char op_setnz    []="setnz";
  446. static const char op_seta    []="seta";
  447. static const char op_setbe    []="setbe";
  448.  
  449. static const char op_shl    []="shl";
  450. static const char op_shld    []="shld";
  451. static const char op_shr    []="shr";
  452. static const char op_shrd    []="shrd";
  453. static const char op_sgdt    []="sgdt";
  454. static const char op_sidt    []="sidt";
  455. static const char op_sldt    []="sldt";
  456. static const char op_smsw    []="smsw";
  457. static const char op_stc    []="stc";
  458. static const char op_std    []="std";
  459. static const char op_sti    []="sti";
  460. static const char op_str    []="str";
  461. static const char op_stosb    []="stosb";
  462. static const char op_stosd    []="stosd";
  463. static const char op_sub    []="sub";
  464. static const char op_test    []="test";
  465. static const char op_ud2    []="ud2";
  466. static const char op_verr    []="verr";
  467. static const char op_verw    []="verw";
  468. static const char op_wait    []="wait";
  469. static const char op_wbinvd    []="wbinvd";
  470. static const char op_wrmsr    []="wrmsr";
  471. static const char op_xadd    []="xadd";
  472. static const char op_xchg    []="xchg";
  473. static const char op_xlat    []="xlat";
  474. static const char op_xor    []="xor";
  475.  
  476. // AMD 3DNow! instructions
  477.  
  478. static const char op_femms        []="femms";
  479. static const char op_pfadd        []="pfadd";
  480. static const char op_pfsub        []="pfsub";
  481. static const char op_pfsubr        []="pfsubr";
  482. static const char op_pfacc        []="pfacc";
  483. static const char op_pfmul        []="pfmul";
  484. static const char op_pfcmpge    []="pfcmpge";
  485. static const char op_pfcmpgt    []="pfcmpgt";
  486. static const char op_pfcmpeq    []="pfcmpeq";
  487. static const char op_pfmin        []="pfmin";
  488. static const char op_pfmax        []="pfmax";
  489. static const char op_pi2fd        []="pi2fd";
  490. static const char op_pf2id        []="pf2id";
  491. static const char op_pfrcp        []="pfrcp";
  492. static const char op_pfrsqrt    []="pfrsqrt";
  493. static const char op_pfrcpit1    []="pfrcpit1";
  494. static const char op_pfrsqit1    []="pfsqit1";
  495. static const char op_pfrcpit2    []="pfrcpit2";
  496. static const char op_pmulhrw    []="pmulhrw";
  497. static const char op_prefetch    []="prefetch";
  498. static const char op_prefetchw    []="prefetchw";
  499.  
  500. struct x86op {
  501.     const char *name;
  502.     long flags;
  503. };
  504.  
  505. static const struct x86op singops[]={
  506. /* 00 */    op_add,            ADDR2(ADDR_Eb,ADDR_Gb),
  507. /* 01 */    op_add,            ADDR2(ADDR_Ev,ADDR_Gv),
  508. /* 02 */    op_add,            ADDR2(ADDR_Gb,ADDR_Eb),
  509. /* 03 */    op_add,            ADDR2(ADDR_Gv,ADDR_Ev),
  510. /* 04 */    op_add,            ADDR2(ADDR_AL,ADDR_Ib),
  511. /* 05 */    op_add,            ADDR2(ADDR_EAX,ADDR_Iv),
  512. /* 06 */    op_push,        ADDR_ES,
  513. /* 07 */    op_pop,            ADDR_ES,
  514. /* 08 */    op_or,            ADDR2(ADDR_Eb,ADDR_Gb),
  515. /* 09 */    op_or,            ADDR2(ADDR_Ev,ADDR_Gv),
  516. /* 0a */    op_or,            ADDR2(ADDR_Gb,ADDR_Eb),
  517. /* 0b */    op_or,            ADDR2(ADDR_Gv,ADDR_Ev),
  518. /* 0c */    op_or,            ADDR2(ADDR_AL,ADDR_Ib),
  519. /* 0d */    op_or,            ADDR2(ADDR_EAX,ADDR_Iv),
  520. /* 0e */    op_push,        ADDR_CS,
  521. /* 0f */    NULL,            TYPE(TYPE_0f),
  522. /* 10 */    op_adc,            ADDR2(ADDR_Eb,ADDR_Gb),
  523. /* 11 */    op_adc,            ADDR2(ADDR_Ev,ADDR_Gv),
  524. /* 12 */    op_adc,            ADDR2(ADDR_Gb,ADDR_Eb),
  525. /* 13 */    op_adc,            ADDR2(ADDR_Gv,ADDR_Ev),
  526. /* 14 */    op_adc,            ADDR2(ADDR_AL,ADDR_Ib),
  527. /* 15 */    op_adc,            ADDR2(ADDR_EAX,ADDR_Iv),
  528. /* 16 */    op_push,        ADDR_SS,
  529. /* 17 */    op_pop,            ADDR_SS,
  530. /* 18 */    op_sbb,            ADDR2(ADDR_Eb,ADDR_Gb),
  531. /* 19 */    op_sbb,            ADDR2(ADDR_Ev,ADDR_Gv),
  532. /* 1a */    op_sbb,            ADDR2(ADDR_Gb,ADDR_Eb),
  533. /* 1b */    op_sbb,            ADDR2(ADDR_Gv,ADDR_Ev),
  534. /* 1c */    op_sbb,            ADDR2(ADDR_AL,ADDR_Ib),
  535. /* 1d */    op_sbb,            ADDR2(ADDR_EAX,ADDR_Iv),
  536. /* 1e */    op_push,        ADDR_DS,
  537. /* 1f */    op_pop,            ADDR_DS,
  538. /* 20 */    op_and,            ADDR2(ADDR_Eb,ADDR_Gb),
  539. /* 21 */    op_and,            ADDR2(ADDR_Ev,ADDR_Gv),
  540. /* 22 */    op_and,            ADDR2(ADDR_Gb,ADDR_Eb),
  541. /* 23 */    op_and,            ADDR2(ADDR_Gv,ADDR_Ev),
  542. /* 24 */    op_and,            ADDR2(ADDR_AL,ADDR_Ib),
  543. /* 25 */    op_and,            ADDR2(ADDR_EAX,ADDR_Iv),
  544. /* 26 */    NULL,            TYPE(TYPE_es_override),
  545. /* 27 */    op_daa,            0,
  546. /* 28 */    op_sub,            ADDR2(ADDR_Eb,ADDR_Gb),
  547. /* 29 */    op_sub,            ADDR2(ADDR_Ev,ADDR_Gv),
  548. /* 2a */    op_sub,            ADDR2(ADDR_Gb,ADDR_Eb),
  549. /* 2b */    op_sub,            ADDR2(ADDR_Gv,ADDR_Ev),
  550. /* 2c */    op_sub,            ADDR2(ADDR_AL,ADDR_Ib),
  551. /* 2d */    op_sub,            ADDR2(ADDR_EAX,ADDR_Iv),
  552. /* 2e */    NULL,            TYPE(TYPE_cs_override),
  553. /* 2f */    op_das,            0,
  554. /* 30 */    op_xor,            ADDR2(ADDR_Eb,ADDR_Gb),
  555. /* 31 */    op_xor,            ADDR2(ADDR_Ev,ADDR_Gv),
  556. /* 32 */    op_xor,            ADDR2(ADDR_Gb,ADDR_Eb),
  557. /* 33 */    op_xor,            ADDR2(ADDR_Gv,ADDR_Ev),
  558. /* 34 */    op_xor,            ADDR2(ADDR_AL,ADDR_Ib),
  559. /* 35 */    op_xor,            ADDR2(ADDR_EAX,ADDR_Iv),
  560. /* 36 */    NULL,            TYPE(TYPE_ss_override),
  561. /* 37 */    op_aaa,            0,
  562. /* 38 */    op_cmp,            ADDR2(ADDR_Eb,ADDR_Gb),
  563. /* 39 */    op_cmp,            ADDR2(ADDR_Ev,ADDR_Gv),
  564. /* 3a */    op_cmp,            ADDR2(ADDR_Gb,ADDR_Eb),
  565. /* 3b */    op_cmp,            ADDR2(ADDR_Gv,ADDR_Ev),
  566. /* 3c */    op_cmp,            ADDR2(ADDR_AL,ADDR_Ib),
  567. /* 3d */    op_cmp,            ADDR2(ADDR_EAX,ADDR_Iv),
  568. /* 3e */    NULL,            TYPE(TYPE_ds_override),
  569. /* 3f */    op_aas,            0,
  570. /* 40 */    op_inc,            ADDR_reg32,
  571. /* 41 */    op_inc,            ADDR_reg32,
  572. /* 42 */    op_inc,            ADDR_reg32,
  573. /* 43 */    op_inc,            ADDR_reg32,
  574. /* 44 */    op_inc,            ADDR_reg32,
  575. /* 45 */    op_inc,            ADDR_reg32,
  576. /* 46 */    op_inc,            ADDR_reg32,
  577. /* 47 */    op_inc,            ADDR_reg32,
  578. /* 48 */    op_dec,            ADDR_reg32,
  579. /* 49 */    op_dec,            ADDR_reg32,
  580. /* 4a */    op_dec,            ADDR_reg32,
  581. /* 4b */    op_dec,            ADDR_reg32,
  582. /* 4c */    op_dec,            ADDR_reg32,
  583. /* 4d */    op_dec,            ADDR_reg32,
  584. /* 4e */    op_dec,            ADDR_reg32,
  585. /* 4f */    op_dec,            ADDR_reg32,
  586. /* 50 */    op_push,        ADDR_reg32,
  587. /* 51 */    op_push,        ADDR_reg32,
  588. /* 52 */    op_push,        ADDR_reg32,
  589. /* 53 */    op_push,        ADDR_reg32,
  590. /* 54 */    op_push,        ADDR_reg32,
  591. /* 55 */    op_push,        ADDR_reg32,
  592. /* 56 */    op_push,        ADDR_reg32,
  593. /* 57 */    op_push,        ADDR_reg32,
  594. /* 58 */    op_pop,            ADDR_reg32,
  595. /* 59 */    op_pop,            ADDR_reg32,
  596. /* 5a */    op_pop,            ADDR_reg32,
  597. /* 5b */    op_pop,            ADDR_reg32,
  598. /* 5c */    op_pop,            ADDR_reg32,
  599. /* 5d */    op_pop,            ADDR_reg32,
  600. /* 5e */    op_pop,            ADDR_reg32,
  601. /* 5f */    op_pop,            ADDR_reg32,
  602. /* 60 */    op_pushad,        MOD(MOD16_take_d_off),
  603. /* 61 */    op_popad,        MOD(MOD16_take_d_off),
  604. /* 62 */    op_bound,        ADDR2(ADDR_Gv,ADDR_Ma),
  605. /* 63 */    op_arpl,        ADDR2(ADDR_Ew,ADDR_Gw),
  606. /* 64 */    NULL,            TYPE(TYPE_fs_override),
  607. /* 65 */    NULL,            TYPE(TYPE_gs_override),
  608. /* 66 */    NULL,            TYPE(TYPE_operand_size_override),
  609. /* 67 */    NULL,            TYPE(TYPE_address_size_override),
  610. /* 68 */    op_push,        ADDR_Iv,
  611. /* 69 */    op_imul,        ADDR3(ADDR_Gv,ADDR_Ev,ADDR_Iv),
  612. /* 6a */    op_push,        ADDR_Ib,
  613. /* 6b */    op_imul,        ADDR3(ADDR_Gv,ADDR_Ev,ADDR_Ib),
  614. /* 6c */    op_insb,        ADDR2(ADDR_Yb,ADDR_DX),
  615. /* 6d */    op_insd,        ADDR2(ADDR_Yv,ADDR_DX) | MOD(MOD16_d_to_w),
  616. /* 6e */    op_outsb,        ADDR2(ADDR_DX,ADDR_Xb),
  617. /* 6f */    op_outsd,        ADDR2(ADDR_DX,ADDR_Xv) | MOD(MOD16_d_to_w),
  618. /* 70 */    op_jo,            ADDR_Jb,
  619. /* 71 */    op_jno,            ADDR_Jb,
  620. /* 72 */    op_jc,            ADDR_Jb,
  621. /* 73 */    op_jnc,            ADDR_Jb,
  622. /* 74 */    op_jz,            ADDR_Jb,
  623. /* 75 */    op_jnz,            ADDR_Jb,
  624. /* 76 */    op_jbe,            ADDR_Jb,
  625. /* 77 */    op_ja,            ADDR_Jb,
  626. /* 78 */    op_js,            ADDR_Jb,
  627. /* 79 */    op_jns,            ADDR_Jb,
  628. /* 7a */    op_jp,            ADDR_Jb,
  629. /* 7b */    op_jnp,            ADDR_Jb,
  630. /* 7c */    op_jl,            ADDR_Jb,
  631. /* 7d */    op_jge,            ADDR_Jb,
  632. /* 7e */    op_jle,            ADDR_Jb,
  633. /* 7f */    op_jg,            ADDR_Jb,
  634. /* 80 */    NULL,            ADDR2(ADDR_Eb,ADDR_Ib) | GROUP(1),
  635. /* 81 */    NULL,            ADDR2(ADDR_Ev,ADDR_Iv) | GROUP(1),
  636. /* 82 */    NULL,            ADDR2(ADDR_Eb,ADDR_Ib) | GROUP(1),
  637. /* 83 */    NULL,            ADDR2(ADDR_Ev,ADDR_Ibs) | GROUP(1),
  638. /* 84 */    op_test,        ADDR2(ADDR_Eb,ADDR_Gb),
  639. /* 85 */    op_test,        ADDR2(ADDR_Ev,ADDR_Gv),
  640. /* 86 */    op_xchg,        ADDR2(ADDR_Eb,ADDR_Gb),
  641. /* 87 */    op_xchg,        ADDR2(ADDR_Ev,ADDR_Gv),
  642. /* 88 */    op_mov,            ADDR2(ADDR_Eb,ADDR_Gb),
  643. /* 89 */    op_mov,            ADDR2(ADDR_Ev,ADDR_Gv),
  644. /* 8a */    op_mov,            ADDR2(ADDR_Gb,ADDR_Eb),
  645. /* 8b */    op_mov,            ADDR2(ADDR_Gv,ADDR_Ev),
  646. /* 8c */    op_mov,            ADDR2(ADDR_Ew,ADDR_Sw),
  647. /* 8d */    op_lea,            ADDR2(ADDR_Gv,ADDR_M),
  648. /* 8e */    op_mov,            ADDR2(ADDR_Sw,ADDR_Ew),
  649. /* 8f */    op_pop,            ADDR_Ev,
  650. /* 90 */    op_nop,            0,
  651. /* 91 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  652. /* 92 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  653. /* 93 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  654. /* 94 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  655. /* 95 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  656. /* 96 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  657. /* 97 */    op_xchg,        ADDR2(ADDR_EAX,ADDR_reg32),
  658. /* 98 */    op_cbw,            0,
  659. /* 99 */    op_cdq,            MOD(MOD16_dq_to_wd),
  660. /* 9a */    op_call,        ADDR_Ap,
  661. /* 9b */    op_wait,        0,
  662. /* 9c */    op_pushfd,        MOD(MOD16_take_d_off),
  663. /* 9d */    op_popfd,        MOD(MOD16_take_d_off),
  664. /* 9e */    op_sahf,        0,
  665. /* 9f */    op_lahf,        0,
  666. /* a0 */    op_mov,            ADDR2(ADDR_AL,ADDR_Ob),
  667. /* a1 */    op_mov,            ADDR2(ADDR_EAX,ADDR_Ov),
  668. /* a2 */    op_mov,            ADDR2(ADDR_Ob,ADDR_AL),
  669. /* a3 */    op_mov,            ADDR2(ADDR_Ob,ADDR_EAX),
  670. /* a4 */    op_movsb,        ADDR2(ADDR_Xb,ADDR_Yb),
  671. /* a5 */    op_movsd,        ADDR2(ADDR_Xv,ADDR_Yv) | MOD(MOD16_d_to_w),
  672. /* a6 */    op_cmpsb,        ADDR2(ADDR_Xb,ADDR_Yb),
  673. /* a7 */    op_cmpsd,        ADDR2(ADDR_Xv,ADDR_Yv) | MOD(MOD16_d_to_w),
  674. /* a8 */    op_test,        ADDR2(ADDR_AL,ADDR_Ib),
  675. /* a9 */    op_test,        ADDR2(ADDR_EAX,ADDR_Iv),
  676. /* aa */    op_stosb,        ADDR2(ADDR_Yb,ADDR_AL),
  677. /* ab */    op_stosd,        ADDR2(ADDR_Yv,ADDR_EAX) | MOD(MOD16_d_to_w),
  678. /* ac */    op_lodsb,        ADDR2(ADDR_AL,ADDR_Xb),
  679. /* ad */    op_lodsd,        ADDR2(ADDR_EAX,ADDR_Xv) | MOD(MOD16_d_to_w),
  680. /* ae */    op_scasb,        ADDR2(ADDR_AL,ADDR_Yb),
  681. /* af */    op_scasd,        ADDR2(ADDR_EAX,ADDR_Yv) | MOD(MOD16_d_to_w),
  682. /* b0 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  683. /* b1 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  684. /* b2 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  685. /* b3 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  686. /* b4 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  687. /* b5 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  688. /* b6 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  689. /* b7 */    op_mov,            ADDR2(ADDR_reg8,ADDR_Ib),
  690. /* b8 */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  691. /* b9 */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  692. /* ba */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  693. /* bb */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  694. /* bc */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  695. /* bd */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  696. /* be */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  697. /* bf */    op_mov,            ADDR2(ADDR_reg32,ADDR_Iv),
  698. /* c0 */    NULL,            ADDR2(ADDR_Eb,ADDR_Ib) | GROUP(2),
  699. /* c1 */    NULL,            ADDR2(ADDR_Ev,ADDR_Ib) | GROUP(2),
  700. /* c2 */    op_ret,            ADDR_Iw,
  701. /* c3 */    op_ret,            0,
  702. /* c4 */    op_les,            ADDR2(ADDR_Gv,ADDR_Mp),
  703. /* c5 */    op_lds,            ADDR2(ADDR_Gv,ADDR_Mp),
  704. /* c6 */    op_mov,            ADDR2(ADDR_Eb,ADDR_Ib),
  705. /* c7 */    op_mov,            ADDR2(ADDR_Ev,ADDR_Iv),
  706. /* c8 */    op_enter,        ADDR2(ADDR_Iw,ADDR_Ib),
  707. /* c9 */    op_leave,        0,
  708. /* ca */    op_retf,        ADDR_Iw,
  709. /* cb */    op_retf,        0,
  710. /* cc */    op_int3,        0,
  711. /* cd */    op_int,            ADDR_Ib,
  712. /* ce */    op_into,        0,
  713. /* cf */    op_iret,        0,
  714. /* d0 */    NULL,            ADDR2(ADDR_Eb,ADDR_1) | GROUP(2),
  715. /* d1 */    NULL,            ADDR2(ADDR_Ev,ADDR_1) | GROUP(2),
  716. /* d2 */    NULL,            ADDR2(ADDR_Eb,ADDR_CL) | GROUP(2),
  717. /* d3 */    NULL,            ADDR2(ADDR_Ev,ADDR_CL) | GROUP(2),
  718. /* d4 */    op_aam,            ADDR_Ib,
  719. /* d5 */    op_aad,            ADDR_Ib,
  720. /* d6 */    NULL,            0,
  721. /* d7 */    op_xlat,        0,
  722. /* d8 */    NULL,            GROUP(13),    // D8-DF: floating point escapes
  723. /* d9 */    NULL,            GROUP(14),
  724. /* da */    NULL,            GROUP(15),
  725. /* db */    NULL,            GROUP(16),
  726. /* dc */    NULL,            GROUP(17),
  727. /* dd */    NULL,            GROUP(18),
  728. /* de */    NULL,            GROUP(19),
  729. /* df */    NULL,            GROUP(20),
  730. /* e0 */    op_loopn,        ADDR_Jb,
  731. /* e1 */    op_loope,        ADDR_Jb,
  732. /* e2 */    op_loop,        ADDR_Jb,
  733. /* e3 */    op_jecxz,        ADDR_Jb,
  734. /* e4 */    op_in,            ADDR2(ADDR_AL,ADDR_Ib),
  735. /* e5 */    op_in,            ADDR2(ADDR_EAX,ADDR_Ib),
  736. /* e6 */    op_out,            ADDR2(ADDR_Ib,ADDR_AL),
  737. /* e7 */    op_out,            ADDR2(ADDR_Ib,ADDR_EAX),
  738. /* e8 */    op_call,        ADDR_Jv,
  739. /* e9 */    op_jmp,            ADDR_Jv,
  740. /* ea */    op_jmp,            ADDR_Ap,
  741. /* eb */    op_jmp,            ADDR_Jb,
  742. /* ec */    op_in,            ADDR2(ADDR_AL,ADDR_DX),
  743. /* ed */    op_in,            ADDR2(ADDR_EAX,ADDR_DX),
  744. /* ee */    op_out,            ADDR2(ADDR_DX,ADDR_AL),
  745. /* ef */    op_out,            ADDR2(ADDR_DX,ADDR_EAX),
  746. /* f0 */    op_lock,        TYPE(TYPE_prefix),
  747. /* f1 */    NULL,            0,
  748. /* f2 */    op_repne,        TYPE(TYPE_prefix),
  749. /* f3 */    op_rep,            TYPE(TYPE_prefix),
  750. /* f4 */    op_hlt,            0,
  751. /* f5 */    op_cmc,            0,
  752. /* f6 */    NULL,            ADDR_Eb | GROUP(3),
  753. /* f7 */    NULL,            ADDR_Ev | GROUP(3),
  754. /* f8 */    op_clc,            0,
  755. /* f9 */    op_stc,            0,
  756. /* fa */    op_cli,            0,
  757. /* fb */    op_sti,            0,
  758. /* fc */    op_cld,            0,
  759. /* fd */    op_std,            0,
  760. /* fe */    NULL,            GROUP(4),
  761. /* ff */    NULL,            GROUP(5),
  762. };
  763.  
  764. static const struct x86op prefix0f_ops[]={
  765. /* 00 */    NULL,            GROUP(6),
  766. /* 01 */    NULL,            0,
  767. /* 02 */    op_lar,            ADDR2(ADDR_Gv, ADDR_Ew),
  768. /* 03 */    op_lsl,            ADDR2(ADDR_Gv, ADDR_Ew),
  769. /* 04 */    NULL,            0,
  770. /* 05 */    NULL,            0,
  771. /* 06 */    op_clts,        0,
  772. /* 07 */    NULL,            0,
  773. /* 08 */    op_invd,        0,
  774. /* 09 */    op_wbinvd,        0,
  775. /* 0a */    NULL,            0,
  776. /* 0b */    op_ud2,            0,
  777. /* 0c */    NULL,            0,
  778. /* 0d */    NULL,            GROUP(21),        // 3DNow! prefetch instructions
  779. /* 0e */    op_femms,        0,
  780. /* 0f */    NULL,            SPECIAL_3DNOW,
  781. /* 10 */    NULL,            0,
  782. /* 11 */    NULL,            0,
  783. /* 12 */    NULL,            0,
  784. /* 13 */    NULL,            0,
  785. /* 14 */    NULL,            0,
  786. /* 15 */    NULL,            0,
  787. /* 16 */    NULL,            0,
  788. /* 17 */    NULL,            0,
  789. /* 18 */    NULL,            0,
  790. /* 19 */    NULL,            0,
  791. /* 1a */    NULL,            0,
  792. /* 1b */    NULL,            0,
  793. /* 1c */    NULL,            0,
  794. /* 1d */    NULL,            0,
  795. /* 1e */    NULL,            0,
  796. /* 1f */    NULL,            0,
  797. /* 20 */    op_mov,            ADDR2(ADDR_Rd, ADDR_Cd),
  798. /* 21 */    op_mov,            ADDR2(ADDR_Rd, ADDR_Dd),
  799. /* 22 */    op_mov,            ADDR2(ADDR_Cd, ADDR_Rd),
  800. /* 23 */    op_mov,            ADDR2(ADDR_Dd, ADDR_Rd),
  801. /* 24 */    NULL,            0,
  802. /* 25 */    NULL,            0,
  803. /* 26 */    NULL,            0,
  804. /* 27 */    NULL,            0,
  805. /* 28 */    NULL,            0,
  806. /* 29 */    NULL,            0,
  807. /* 2a */    NULL,            0,
  808. /* 2b */    NULL,            0,
  809. /* 2c */    NULL,            0,
  810. /* 2d */    NULL,            0,
  811. /* 2e */    NULL,            0,
  812. /* 2f */    NULL,            0,
  813. /* 30 */    op_wrmsr,        0,
  814. /* 31 */    op_rdtsc,        0,
  815. /* 32 */    op_rdmsr,        0,
  816. /* 33 */    op_rdpmc,        0,
  817. /* 34 */    NULL,            0,
  818. /* 35 */    NULL,            0,
  819. /* 36 */    NULL,            0,
  820. /* 37 */    NULL,            0,
  821. /* 38 */    NULL,            0,
  822. /* 39 */    NULL,            0,
  823. /* 3a */    NULL,            0,
  824. /* 3b */    NULL,            0,
  825. /* 3c */    NULL,            0,
  826. /* 3d */    NULL,            0,
  827. /* 3e */    NULL,            0,
  828. /* 3f */    NULL,            0,
  829. /* 40 */    op_cmovo,        ADDR2(ADDR_Gv,ADDR_Ev),
  830. /* 41 */    op_cmovno,        ADDR2(ADDR_Gv,ADDR_Ev),
  831. /* 42 */    op_cmovc,        ADDR2(ADDR_Gv,ADDR_Ev),
  832. /* 43 */    op_cmovnc,        ADDR2(ADDR_Gv,ADDR_Ev),
  833. /* 44 */    op_cmovz,        ADDR2(ADDR_Gv,ADDR_Ev),
  834. /* 45 */    op_cmovnz,        ADDR2(ADDR_Gv,ADDR_Ev),
  835. /* 46 */    op_cmovbe,        ADDR2(ADDR_Gv,ADDR_Ev),
  836. /* 47 */    op_cmova,        ADDR2(ADDR_Gv,ADDR_Ev),
  837. /* 48 */    op_cmovs,        ADDR2(ADDR_Gv,ADDR_Ev),
  838. /* 49 */    op_cmovns,        ADDR2(ADDR_Gv,ADDR_Ev),
  839. /* 4a */    op_cmovp,        ADDR2(ADDR_Gv,ADDR_Ev),
  840. /* 4b */    op_cmovnp,        ADDR2(ADDR_Gv,ADDR_Ev),
  841. /* 4c */    op_cmovl,        ADDR2(ADDR_Gv,ADDR_Ev),
  842. /* 4d */    op_cmovge,        ADDR2(ADDR_Gv,ADDR_Ev),
  843. /* 4e */    op_cmovle,        ADDR2(ADDR_Gv,ADDR_Ev),
  844. /* 4f */    op_cmovg,        ADDR2(ADDR_Gv,ADDR_Ev),
  845. /* 50 */    NULL,            0,
  846. /* 51 */    NULL,            0,
  847. /* 52 */    NULL,            0,
  848. /* 53 */    NULL,            0,
  849. /* 54 */    NULL,            0,
  850. /* 55 */    NULL,            0,
  851. /* 56 */    NULL,            0,
  852. /* 57 */    NULL,            0,
  853. /* 58 */    NULL,            0,
  854. /* 59 */    NULL,            0,
  855. /* 5a */    NULL,            0,
  856. /* 5b */    NULL,            0,
  857. /* 5c */    NULL,            0,
  858. /* 5d */    NULL,            0,
  859. /* 5e */    NULL,            0,
  860. /* 5f */    NULL,            0,
  861. /* 60 */    op_punpcklbw,    ADDR2(ADDR_Pq,ADDR_Qd),
  862. /* 61 */    op_punpcklwd,    ADDR2(ADDR_Pq,ADDR_Qd),
  863. /* 62 */    op_punpckldq,    ADDR2(ADDR_Pq,ADDR_Qd),
  864. /* 63 */    op_packusdw,    ADDR2(ADDR_Pq,ADDR_Qd),
  865. /* 64 */    op_pcmpgtb,        ADDR2(ADDR_Pq,ADDR_Qd),
  866. /* 65 */    op_pcmpgtw,        ADDR2(ADDR_Pq,ADDR_Qd),
  867. /* 66 */    op_pcmpgtd,        ADDR2(ADDR_Pq,ADDR_Qd),
  868. /* 67 */    op_packsswb,    ADDR2(ADDR_Pq,ADDR_Qd),
  869. /* 68 */    op_punpckhbw,    ADDR2(ADDR_Pq,ADDR_Qd),
  870. /* 69 */    op_punpckhwd,    ADDR2(ADDR_Pq,ADDR_Qd),
  871. /* 6a */    op_punpckhdq,    ADDR2(ADDR_Pq,ADDR_Qd),
  872. /* 6b */    op_packssdw,    ADDR2(ADDR_Pq,ADDR_Qd),
  873. /* 6c */    NULL,            0,
  874. /* 6d */    NULL,            0,
  875. /* 6e */    op_movd,        ADDR2(ADDR_Pd,ADDR_Ed),
  876. /* 6f */    op_movq,        ADDR2(ADDR_Pq,ADDR_Qq),
  877. /* 70 */    NULL,            0,
  878. /* 71 */    NULL,            GROUP(10),
  879. /* 72 */    NULL,            GROUP(11),
  880. /* 73 */    NULL,            GROUP(12),
  881. /* 74 */    op_pcmpeqb,        ADDR2(ADDR_Pq,ADDR_Qd),
  882. /* 75 */    op_pcmpeqw,        ADDR2(ADDR_Pq,ADDR_Qd),
  883. /* 76 */    op_pcmpeqd,        ADDR2(ADDR_Pq,ADDR_Qd),
  884. /* 77 */    op_emms,        0,
  885. /* 78 */    NULL,            0,
  886. /* 79 */    NULL,            0,
  887. /* 7a */    NULL,            0,
  888. /* 7b */    NULL,            0,
  889. /* 7c */    NULL,            0,
  890. /* 7d */    NULL,            0,
  891. /* 7e */    op_movd,        ADDR2(ADDR_Ed,ADDR_Pd),
  892. /* 7f */    op_movq,        ADDR2(ADDR_Qq,ADDR_Pq),
  893. /* 80 */    op_jo,            ADDR_Jv,
  894. /* 81 */    op_jno,            ADDR_Jv,
  895. /* 82 */    op_jc,            ADDR_Jv,
  896. /* 83 */    op_jnc,            ADDR_Jv,
  897. /* 84 */    op_jz,            ADDR_Jv,
  898. /* 85 */    op_jnz,            ADDR_Jv,
  899. /* 86 */    op_jbe,            ADDR_Jv,
  900. /* 87 */    op_ja,            ADDR_Jv,
  901. /* 88 */    op_js,            ADDR_Jv,
  902. /* 89 */    op_jns,            ADDR_Jv,
  903. /* 8a */    op_jp,            ADDR_Jv,
  904. /* 8b */    op_jnp,            ADDR_Jv,
  905. /* 8c */    op_jl,            ADDR_Jv,
  906. /* 8d */    op_jge,            ADDR_Jv,
  907. /* 8e */    op_jle,            ADDR_Jv,
  908. /* 8f */    op_jg,            ADDR_Jv,
  909. /* 90 */    op_seto,        ADDR_Eb,
  910. /* 91 */    op_setno,        ADDR_Eb,
  911. /* 92 */    op_setc,        ADDR_Eb,
  912. /* 93 */    op_setnc,        ADDR_Eb,
  913. /* 94 */    op_setz,        ADDR_Eb,
  914. /* 95 */    op_setnz,        ADDR_Eb,
  915. /* 96 */    op_setbe,        ADDR_Eb,
  916. /* 97 */    op_seta,        ADDR_Eb,
  917. /* 98 */    op_sets,        ADDR_Eb,
  918. /* 99 */    op_setns,        ADDR_Eb,
  919. /* 9a */    op_setp,        ADDR_Eb,
  920. /* 9b */    op_setnp,        ADDR_Eb,
  921. /* 9c */    op_setl,        ADDR_Eb,
  922. /* 9d */    op_setge,        ADDR_Eb,
  923. /* 9e */    op_setle,        ADDR_Eb,
  924. /* 9f */    op_setg,        ADDR_Eb,
  925. /* a0 */    op_push,        ADDR_FS,
  926. /* a1 */    op_pop,            ADDR_FS,
  927. /* a2 */    op_cpuid,        0,
  928. /* a3 */    op_bt,            ADDR2(ADDR_Ev,ADDR_Gv),
  929. /* a4 */    op_shld,        ADDR3(ADDR_Ev,ADDR_Gv,ADDR_Ib),
  930. /* a5 */    op_shld,        ADDR3(ADDR_Ev,ADDR_Gv,ADDR_CL),
  931. /* a6 */    NULL,            0,
  932. /* a7 */    NULL,            0,
  933. /* a8 */    op_push,        ADDR_GS,
  934. /* a9 */    op_pop,            ADDR_GS,
  935. /* aa */    op_rsm,            0,
  936. /* ab */    op_bts,            ADDR2(ADDR_Ev,ADDR_Gv),
  937. /* ac */    op_shrd,        ADDR3(ADDR_Ev,ADDR_Gv,ADDR_Ib),
  938. /* ad */    op_shrd,        ADDR3(ADDR_Ev,ADDR_Gv,ADDR_CL),
  939. /* ae */    NULL,            0,
  940. /* af */    op_imul,        ADDR2(ADDR_Gv,ADDR_Ev),
  941. /* b0 */    op_cmpxchg,        ADDR2(ADDR_Eb,ADDR_Gb),
  942. /* b1 */    op_cmpxchg,        ADDR2(ADDR_Ev,ADDR_Gv),
  943. /* b2 */    op_lss,            ADDR_Mp,
  944. /* b3 */    op_btr,            ADDR2(ADDR_Ev,ADDR_Gv),
  945. /* b4 */    op_lfs,            ADDR_Mp,
  946. /* b5 */    op_lgs,            ADDR_Mp,
  947. /* b6 */    op_movzx,        ADDR2(ADDR_Gv,ADDR_Eb),
  948. /* b7 */    op_movzx,        ADDR2(ADDR_Gv,ADDR_Ew),
  949. /* b8 */    NULL,            0,
  950. /* b9 */    op_invalid,        0,
  951. /* ba */    NULL,            GROUP(8),
  952. /* bb */    op_btc,            ADDR2(ADDR_Ev,ADDR_Gv),
  953. /* bc */    op_bsf,            ADDR2(ADDR_Gv,ADDR_Ev),
  954. /* bd */    op_bsr,            ADDR2(ADDR_Gv,ADDR_Ev),
  955. /* be */    op_movsx,        ADDR2(ADDR_Gv,ADDR_Eb),
  956. /* bf */    op_movsx,        ADDR2(ADDR_Gv,ADDR_Ew),
  957. /* c0 */    op_xadd,        ADDR2(ADDR_Eb,ADDR_Gb),
  958. /* c1 */    op_xadd,        ADDR2(ADDR_Ev,ADDR_Gv),
  959. /* c2 */    NULL,            0,
  960. /* c3 */    NULL,            0,
  961. /* c4 */    NULL,            0,
  962. /* c5 */    NULL,            0,
  963. /* c6 */    NULL,            0,
  964. /* c7 */    NULL,            GROUP(9),
  965. /* c8 */    op_bswap,        ADDR_reg32,
  966. /* c9 */    op_bswap,        ADDR_reg32,
  967. /* ca */    op_bswap,        ADDR_reg32,
  968. /* cb */    op_bswap,        ADDR_reg32,
  969. /* cc */    op_bswap,        ADDR_reg32,
  970. /* cd */    op_bswap,        ADDR_reg32,
  971. /* ce */    op_bswap,        ADDR_reg32,
  972. /* cf */    op_bswap,        ADDR_reg32,
  973. /* d0 */    NULL,            0,
  974. /* d1 */    op_psrlw,        ADDR2(ADDR_Pq,ADDR_Qd),
  975. /* d2 */    op_psrld,        ADDR2(ADDR_Pq,ADDR_Qd),
  976. /* d3 */    op_psrlq,        ADDR2(ADDR_Pq,ADDR_Qd),
  977. /* d4 */    NULL,            0,
  978. /* d5 */    op_pmullw,        ADDR2(ADDR_Pq,ADDR_Qd),
  979. /* d6 */    NULL,            0,
  980. /* d7 */    NULL,            0,
  981. /* d8 */    op_psubusb,        ADDR2(ADDR_Pq,ADDR_Qq),
  982. /* d9 */    op_psubusw,        ADDR2(ADDR_Pq,ADDR_Qq),
  983. /* da */    NULL,            0,
  984. /* db */    op_pand,        ADDR2(ADDR_Pq,ADDR_Qq),
  985. /* dc */    op_paddusb,        ADDR2(ADDR_Pq,ADDR_Qq),
  986. /* dd */    op_paddusw,        ADDR2(ADDR_Pq,ADDR_Qq),
  987. /* de */    NULL,            0,
  988. /* df */    op_pandn,        ADDR2(ADDR_Pq,ADDR_Qq),
  989. /* e0 */    NULL,            0,
  990. /* e1 */    op_psraw,        ADDR2(ADDR_Pq,ADDR_Qd),
  991. /* e2 */    op_psrad,        ADDR2(ADDR_Pq,ADDR_Qd),
  992. /* e3 */    NULL,            0,
  993. /* e4 */    NULL,            0,
  994. /* e5 */    op_pmulhw,        ADDR2(ADDR_Pq,ADDR_Qd),
  995. /* e6 */    NULL,            0,
  996. /* e7 */    NULL,            0,
  997. /* e8 */    op_psubsb,        ADDR2(ADDR_Pq,ADDR_Qd),
  998. /* e9 */    op_psubsw,        ADDR2(ADDR_Pq,ADDR_Qd),
  999. /* ea */    NULL,            0,
  1000. /* eb */    op_por,            ADDR2(ADDR_Pq,ADDR_Qd),
  1001. /* ec */    op_paddsb,        ADDR2(ADDR_Pq,ADDR_Qd),
  1002. /* ed */    op_paddsw,        ADDR2(ADDR_Pq,ADDR_Qd),
  1003. /* ee */    NULL,            0,
  1004. /* ef */    op_pxor,        ADDR2(ADDR_Pq,ADDR_Qd),
  1005. /* f0 */    NULL,            0,
  1006. /* f1 */    op_psllw,        ADDR2(ADDR_Pq,ADDR_Qd),
  1007. /* f2 */    op_pslld,        ADDR2(ADDR_Pq,ADDR_Qd),
  1008. /* f3 */    op_psllq,        ADDR2(ADDR_Pq,ADDR_Qd),
  1009. /* f4 */    NULL,            0,
  1010. /* f5 */    op_pmaddwd,        ADDR2(ADDR_Pq,ADDR_Qd),
  1011. /* f6 */    NULL,            0,
  1012. /* f7 */    NULL,            0,
  1013. /* f8 */    op_psubb,        ADDR2(ADDR_Pq,ADDR_Qd),
  1014. /* f9 */    op_psubw,        ADDR2(ADDR_Pq,ADDR_Qd),
  1015. /* fa */    op_psubd,        ADDR2(ADDR_Pq,ADDR_Qd),
  1016. /* fb */    NULL,            0,
  1017. /* fc */    op_paddb,        ADDR2(ADDR_Pq,ADDR_Qd),
  1018. /* fd */    op_paddw,        ADDR2(ADDR_Pq,ADDR_Qd),
  1019. /* fe */    op_paddd,        ADDR2(ADDR_Pq,ADDR_Qd),
  1020. /* ff */    NULL,            0,
  1021. };
  1022.  
  1023. static const struct x86op group1_ops[]={
  1024. /* 000 */    op_add,            0,
  1025. /* 001 */    op_or,            0,
  1026. /* 010 */    op_adc,            0,
  1027. /* 011 */    op_sbb,            0,
  1028. /* 100 */    op_and,            0,
  1029. /* 101 */    op_sub,            0,
  1030. /* 110 */    op_xor,            0,
  1031. /* 111 */    op_cmp,            0,
  1032. };
  1033.  
  1034. static const struct x86op group2_ops[]={
  1035. /* 000 */    op_rol,            0,
  1036. /* 001 */    op_ror,            0,
  1037. /* 010 */    op_rcl,            0,
  1038. /* 011 */    op_rcr,            0,
  1039. /* 100 */    op_shl,            0,
  1040. /* 101 */    op_shr,            0,
  1041. /* 110 */    NULL,            0,
  1042. /* 111 */    op_sar,            0,
  1043. };
  1044.  
  1045. static const struct x86op group3_ops[]={
  1046. /* 000 */    op_test,        ADDR1(ADDR_Idep),
  1047. /* 001 */    NULL,            0,
  1048. /* 010 */    op_not,            0,
  1049. /* 011 */    op_neg,            0,
  1050. /* 100 */    op_mul,            0,
  1051. /* 101 */    op_imul,        0,
  1052. /* 110 */    op_div,            0,
  1053. /* 111 */    op_idiv,        0,
  1054. };
  1055.  
  1056. static const struct x86op group4_ops[]={
  1057. /* 000 */    op_inc,            ADDR_Eb,
  1058. /* 001 */    op_dec,            ADDR_Eb,
  1059. /* 010 */    NULL,            0,
  1060. /* 011 */    NULL,            0,
  1061. /* 100 */    NULL,            0,
  1062. /* 101 */    NULL,            0,
  1063. /* 110 */    NULL,            0,
  1064. /* 111 */    NULL,            0,
  1065. };
  1066.  
  1067. static const struct x86op group5_ops[]={
  1068. /* 000 */    op_inc,            ADDR_Ev,
  1069. /* 001 */    op_dec,            ADDR_Ev,
  1070. /* 010 */    op_call,        ADDR_Ev,
  1071. /* 011 */    op_call,        ADDR_Ep,
  1072. /* 100 */    op_jmp,            ADDR_Ev,
  1073. /* 101 */    op_jmp,            ADDR_Ep,
  1074. /* 110 */    op_push,        ADDR_Ev,
  1075. /* 111 */    NULL,            0,
  1076. };
  1077.  
  1078. static const struct x86op group6_ops[]={
  1079. /* 000 */    op_sldt,        ADDR_Ew,
  1080. /* 001 */    op_str,            ADDR_Ew,
  1081. /* 010 */    op_lldt,        ADDR_Ew,
  1082. /* 011 */    op_ltr,            ADDR_Ew,
  1083. /* 100 */    op_verr,        ADDR_Ew,
  1084. /* 101 */    op_verw,        ADDR_Ew,
  1085. /* 110 */    NULL,            0,
  1086. /* 111 */    NULL,            0,
  1087. };
  1088.  
  1089. static const struct x86op group7_ops[]={
  1090. /* 000 */    op_sgdt,        ADDR_M,
  1091. /* 001 */    op_sidt,        ADDR_M,
  1092. /* 010 */    op_lgdt,        ADDR_M,
  1093. /* 011 */    op_lidt,        ADDR_M,
  1094. /* 100 */    op_smsw,        ADDR_Ew,
  1095. /* 101 */    NULL,            0,
  1096. /* 110 */    op_lmsw,        ADDR_Ew,
  1097. /* 111 */    op_invlpg,        0,
  1098. };
  1099.  
  1100. static const struct x86op group8_ops[]={
  1101. /* 000 */    NULL,            0,
  1102. /* 001 */    NULL,            0,
  1103. /* 010 */    NULL,            0,
  1104. /* 011 */    NULL,            0,
  1105. /* 100 */    op_bt,            ADDR2(ADDR_Gv, ADDR_Ib),
  1106. /* 101 */    op_bts,            ADDR2(ADDR_Gv, ADDR_Ib),
  1107. /* 110 */    op_btr,            ADDR2(ADDR_Gv, ADDR_Ib),
  1108. /* 111 */    op_btc,            ADDR2(ADDR_Gv, ADDR_Ib),
  1109. };
  1110.  
  1111. static const struct x86op group9_ops[]={
  1112. /* 000 */    NULL,            0,
  1113. /* 001 */    op_cmpxchg8b,    ADDR_M,
  1114. /* 010 */    NULL,            0,
  1115. /* 011 */    NULL,            0,
  1116. /* 100 */    NULL,            0,
  1117. /* 101 */    NULL,            0,
  1118. /* 110 */    NULL,            0,
  1119. /* 111 */    NULL,            0,
  1120. };
  1121.  
  1122. static const struct x86op group10w_ops[]={
  1123. /* 000 */    NULL,            0,
  1124. /* 001 */    NULL,            0,
  1125. /* 010 */    op_psrlw,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1126. /* 011 */    NULL,            0,
  1127. /* 100 */    op_psraw,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1128. /* 101 */    NULL,            0,
  1129. /* 110 */    op_psllw,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1130. /* 111 */    NULL,            0,
  1131. };
  1132.  
  1133. static const struct x86op group10d_ops[]={
  1134. /* 000 */    NULL,            0,
  1135. /* 001 */    NULL,            0,
  1136. /* 010 */    op_psrld,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1137. /* 011 */    NULL,            0,
  1138. /* 100 */    op_psrad,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1139. /* 101 */    NULL,            0,
  1140. /* 110 */    op_pslld,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1141. /* 111 */    NULL,            0,
  1142. };
  1143.  
  1144. static const struct x86op group10q_ops[]={
  1145. /* 000 */    NULL,            0,
  1146. /* 001 */    NULL,            0,
  1147. /* 010 */    op_psrlq,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1148. /* 011 */    NULL,            0,
  1149. /* 100 */    NULL,            0,
  1150. /* 101 */    NULL,            0,
  1151. /* 110 */    op_psllq,        ADDR2(ADDR_Pq2, ADDR_Ib2),
  1152. /* 111 */    NULL,            0,
  1153. };
  1154.  
  1155. static const struct x86op group_fpD8[]={
  1156. /* 000 */    op_fadd,            ADDR_Ed,
  1157. /* 001 */    op_fmul,            ADDR_Ed,
  1158. /* 010 */    op_fcom,            ADDR_Ed,
  1159. /* 011 */    op_fcomp,            ADDR_Ed,
  1160. /* 100 */    op_fsub,            ADDR_Ed,
  1161. /* 101 */    op_fsubr,            ADDR_Ed,
  1162. /* 110 */    op_fdiv,            ADDR_Ed,
  1163. /* 111 */    op_fdivr,            ADDR_Ed,
  1164. };
  1165.  
  1166. static const struct x86op group_fpD9[]={
  1167. /* 000 */    op_fld,                ADDR_Ed,
  1168. /* 001 */    NULL,                0,
  1169. /* 010 */    op_fst,                ADDR_Ed,
  1170. /* 011 */    op_fstp,            ADDR_Ed,
  1171. /* 100 */    op_fldenv,            ADDR_Eb,
  1172. /* 101 */    op_fldcw,            ADDR_Ew,
  1173. /* 110 */    op_fstenv,            ADDR_Eb,
  1174. /* 111 */    op_fstcw,            ADDR_Ew,
  1175. };
  1176.  
  1177. static const struct x86op group_fpDA[]={
  1178. /* 000 */    op_fiadd,            ADDR_Ed,
  1179. /* 001 */    op_fimul,            ADDR_Ed,
  1180. /* 010 */    op_ficom,            ADDR_Ed,
  1181. /* 011 */    op_ficomp,            ADDR_Ed,
  1182. /* 100 */    op_fisub,            ADDR_Ed,
  1183. /* 101 */    op_fisubr,            ADDR_Ed,
  1184. /* 110 */    op_fidiv,            ADDR_Ed,
  1185. /* 111 */    op_fidivr,            ADDR_Ed,
  1186. };
  1187.  
  1188. static const struct x86op group_fpDB[]={
  1189. /* 000 */    op_fild,            ADDR_Ed,
  1190. /* 001 */    NULL,                0,
  1191. /* 010 */    op_fist,            ADDR_Ed,
  1192. /* 011 */    op_fistp,            ADDR_Ed,
  1193. /* 100 */    NULL,                0,
  1194. /* 101 */    op_fld,                ADDR_Ex,
  1195. /* 110 */    NULL,                0,
  1196. /* 111 */    op_fstp,            ADDR_Ex,
  1197. };
  1198.  
  1199. static const struct x86op group_fpDC[]={
  1200. /* 000 */    op_fadd,            ADDR_Eq,
  1201. /* 001 */    op_fmul,            ADDR_Eq,
  1202. /* 010 */    op_fcom,            ADDR_Eq,
  1203. /* 011 */    op_fcomp,            ADDR_Eq,
  1204. /* 100 */    op_fsub,            ADDR_Eq,
  1205. /* 101 */    op_fsubr,            ADDR_Eq,
  1206. /* 110 */    op_fdiv,            ADDR_Eq,
  1207. /* 111 */    op_fdivr,            ADDR_Eq,
  1208. };
  1209.  
  1210. static const struct x86op group_fpDD[]={
  1211. /* 000 */    op_fld,                ADDR_Eq,
  1212. /* 001 */    NULL,                0,
  1213. /* 010 */    op_fst,                ADDR_Eq,
  1214. /* 011 */    op_fstp,            ADDR_Eq,
  1215. /* 100 */    op_frstor,            ADDR_Eb,
  1216. /* 101 */    NULL,                0,
  1217. /* 110 */    op_fsave,            ADDR_Eb,
  1218. /* 111 */    op_fstsw,            ADDR_Ew,
  1219. };
  1220.  
  1221. static const struct x86op group_fpDE[]={
  1222. /* 000 */    op_fiadd,            ADDR_Ew,
  1223. /* 001 */    op_fimul,            ADDR_Ew,
  1224. /* 010 */    op_ficom,            ADDR_Ew,
  1225. /* 011 */    op_ficomp,            ADDR_Ew,
  1226. /* 100 */    op_fisub,            ADDR_Ew,
  1227. /* 101 */    op_fisubr,            ADDR_Ew,
  1228. /* 110 */    op_fidiv,            ADDR_Ew,
  1229. /* 111 */    op_fidivr,            ADDR_Ew,
  1230. };
  1231.  
  1232. static const struct x86op group_fpDF[]={
  1233. /* 000 */    op_fild,            ADDR_Ew,
  1234. /* 001 */    NULL,                0,
  1235. /* 010 */    op_fist,            ADDR_Ew,
  1236. /* 011 */    op_fistp,            ADDR_Ew,
  1237. /* 100 */    op_fbld,            ADDR_Eb,
  1238. /* 101 */    op_fild,            ADDR_Eq,
  1239. /* 110 */    op_fbstp,            ADDR_Eb,
  1240. /* 111 */    op_fistp,            ADDR_Eq,
  1241. };
  1242.  
  1243. static const struct x86op group_3DNow_PREFETCH[]={
  1244. /* 000 */    op_prefetch,        ADDR_Qq,
  1245. /* 001 */    op_prefetchw,        ADDR_Qq,
  1246. /* 010 */    NULL,                0,
  1247. /* 011 */    NULL,                0,
  1248. /* 100 */    NULL,                0,
  1249. /* 101 */    NULL,                0,
  1250. /* 110 */    NULL,                0,
  1251. /* 111 */    NULL,                0,
  1252. };
  1253.  
  1254. static const struct x86op * const groups[]={
  1255.     group1_ops,
  1256.     group2_ops,
  1257.     group3_ops,
  1258.     group4_ops,
  1259.     group5_ops,
  1260.     group6_ops,
  1261.     group7_ops,
  1262.     group8_ops,
  1263.     group9_ops,
  1264.     group10w_ops,
  1265.     group10d_ops,
  1266.     group10q_ops,
  1267.     group_fpD8,
  1268.     group_fpD9,
  1269.     group_fpDA,
  1270.     group_fpDB,
  1271.     group_fpDC,
  1272.     group_fpDD,
  1273.     group_fpDE,
  1274.     group_fpDF,
  1275.     group_3DNow_PREFETCH,
  1276. };
  1277.  
  1278. static const char fp_format_st0_stn[]="st(0),st(%d)";
  1279. static const char fp_format_stn_st0[]="st(%d),st(0)";
  1280. static const char fp_format_stn[]="st(%d)";
  1281.  
  1282. static const char * const fpext_reg_tab[8][8][2]={
  1283.     /* D8 */ {    op_fadd,    fp_format_st0_stn,
  1284.                 op_fmul,    fp_format_st0_stn,
  1285.                 op_fcom,    fp_format_st0_stn,
  1286.                 op_fcomp,    fp_format_st0_stn,
  1287.                 op_fsub,    fp_format_st0_stn,
  1288.                 op_fsubr,    fp_format_st0_stn,
  1289.                 op_fdiv,    fp_format_st0_stn,
  1290.                 op_fdivr,    fp_format_st0_stn,
  1291.              },
  1292.     /* D9 */ {    op_fld,        fp_format_st0_stn,
  1293.                 op_fxch,    fp_format_st0_stn,
  1294.                 NULL,        "fnop\0\0\0\0\0\0\0",
  1295.                 NULL,        NULL,
  1296.                 NULL,        "fchs\0fabs\0\0\0ftst\0fxam\0\0",
  1297.                 NULL,        "fld1\0fldl2t\0fldl2e\0fldpi\0fldlg2\0fldln2\0fldz\0",
  1298.                 NULL,        "f2xm1\0fyl2x\0fptan\0fpatan\0fxtract\0fprem1\0fdecstp\0fincstp",
  1299.                 NULL,        "fprem\0fyl2xp1\0fsqrt\0fsincos\0frndint\0fscale\0fsin\0fcos",
  1300.              },
  1301.     /* DA */ {    op_fcmovb,    fp_format_st0_stn,
  1302.                 op_fcmovbe,    fp_format_st0_stn,
  1303.                 op_fcmove,    fp_format_st0_stn,
  1304.                 op_fcmovu,    fp_format_st0_stn,
  1305.                 NULL,        NULL,
  1306.                 NULL,        "\0fucompp\0\0\0\0\0\0",
  1307.                 NULL,        NULL,
  1308.                 NULL,        NULL,
  1309.              },
  1310.     /* DB */ {    op_fcmovnb,        fp_format_st0_stn,
  1311.                 op_fcmovne,        fp_format_st0_stn,
  1312.                 op_fcmovnbe,    fp_format_st0_stn,
  1313.                 op_fcmovnu,        fp_format_st0_stn,
  1314.                 NULL,            "\0\0fclex\0finit\0\0\0\0",
  1315.                 op_fucomi,        fp_format_st0_stn,
  1316.                 op_fcomi,        fp_format_st0_stn,
  1317.                 NULL,            NULL,
  1318.              },
  1319.     /* DC */ {    op_fadd,    fp_format_stn_st0,
  1320.                 op_fmul,    fp_format_stn_st0,
  1321.                 NULL,        NULL,
  1322.                 NULL,        NULL,
  1323.                 op_fsubr,    fp_format_stn_st0,
  1324.                 op_fsub,    fp_format_stn_st0,
  1325.                 op_fdivr,    fp_format_stn_st0,
  1326.                 op_fdiv,    fp_format_stn_st0,
  1327.              },
  1328.     /* DD */ {    op_ffree,    fp_format_stn,
  1329.                 NULL,        NULL,
  1330.                 op_fst,        fp_format_stn,
  1331.                 op_fstp,    fp_format_stn,
  1332.                 op_fucom,    fp_format_stn,
  1333.                 op_fucomp,    fp_format_stn_st0,
  1334.                 NULL,        NULL,
  1335.                 NULL,        NULL,
  1336.              },
  1337.     /* DE */ {    op_faddp,    fp_format_stn_st0,
  1338.                 op_fmulp,    fp_format_stn_st0,
  1339.                 NULL,        NULL,
  1340.                 NULL,        "\0fcompp\0\0\0\0\0\0",
  1341.                 op_fsubrp,    fp_format_stn_st0,
  1342.                 op_fsubp,    fp_format_stn_st0,
  1343.                 op_fdivrp,    fp_format_stn_st0,
  1344.                 op_fdivp,    fp_format_stn_st0,
  1345.              },
  1346.     /* DF */ {    NULL,        NULL,
  1347.                 NULL,        NULL,
  1348.                 NULL,        NULL,
  1349.                 NULL,        NULL,
  1350.                 NULL,        "fstsw\tax\0\0\0\0\0\0\0",
  1351.                 op_fucomip,    fp_format_st0_stn,
  1352.                 op_fcomip,    fp_format_st0_stn,
  1353.                 NULL,        NULL,
  1354.              },
  1355. };
  1356.  
  1357. static const struct x86_3DNow_op {
  1358.     unsigned char    opcode;
  1359.     struct x86op opdata;
  1360. } group_3DNow[]={
  1361.     {    0x0D,    op_pi2fd,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1362.     {    0x1D,    op_pf2id,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1363.     {    0x90,    op_pfcmpge,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1364.     {    0x94,    op_pfmin,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1365.     {    0x96,    op_pfrcp,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1366.     {    0x97,    op_pfrsqrt,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1367.     {    0x9A,    op_pfsub,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1368.     {    0x9E,    op_pfadd,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1369.     {    0xA0,    op_pfcmpgt,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1370.     {    0xA4,    op_pfmax,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1371.     {    0xA6,    op_pfrcpit1,    ADDR2(ADDR_Pq,ADDR_Qq)    },
  1372.     {    0xA7,    op_pfrsqit1,    ADDR2(ADDR_Pq,ADDR_Qq)    },
  1373.     {    0xAA,    op_pfsubr,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1374.     {    0xAE,    op_pfacc,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1375.     {    0xB0,    op_pfcmpeq,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1376.     {    0xB4,    op_pfmul,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1377.     {    0xB6,    op_pfrcpit2,    ADDR2(ADDR_Pq,ADDR_Qq)    },
  1378.     {    0xB7,    op_pmulhrw,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1379.     {    0xBF,    op_pavgusb,        ADDR2(ADDR_Pq,ADDR_Qq)    },
  1380.     {    0, NULL }
  1381. };
  1382.  
  1383. static const char * const reg8[]={ "al","cl","dl","bl","ah","ch","dh","bh" };
  1384. static const char * const reg16[]={ "ax","cx","dx","bx","sp","bp","si","di" };
  1385. static const char * const reg32[]={ "eax","ecx","edx","ebx","esp","ebp","esi","edi" };
  1386. static const char * const regmmx[]={ "mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7" };
  1387. static const char * const sregs[]={ "es", "cs", "ss", "ds", "fs", "gs" };
  1388.  
  1389. static char *strtack(char *d, const char *s) {
  1390.     char c;
  1391.  
  1392.     while(c=*s++) *d++=c;
  1393.  
  1394.     return d;
  1395. }
  1396.  
  1397. static long regmask_modify, regmask_access, regmask_address;
  1398. static int pipe_force;
  1399. static char *ptr_insert;
  1400. static const char *ptr_insert_type;
  1401.  
  1402. #define PIPE_UV (0)
  1403. #define PIPE_U (1)
  1404. #define PIPE_V (2)
  1405.  
  1406. #define PIPE_RESET_UV() (pipe_force = PIPE_UV)
  1407. #define PIPE_FORCE_U() (pipe_force = PIPE_U)
  1408. #define PIPE_FORCE_V() (pipe_force = PIPE_V)
  1409.  
  1410. #define DATA_ACCESS_32(r) (regmask_access |= 0x1L<<(r))
  1411. #define DATA_ACCESS_FP(r) (regmask_access |= 0x100L<<(r))
  1412. #define DATA_ACCESS_MMX DATA_ACCESS_FP
  1413. #define DATA_ACCESS_SEGMENT(r) (regmask_access |= 0x10000L<<(r))
  1414. #define ADDRESS_ACCESS_32(r) (regmask_address |= 0x1L<<(r))
  1415.  
  1416. static void disasm_modrm(unsigned char *&sptr, BOOL big, char *&buf, BOOL is_32_op, BOOL is_32_addr, const char *ptrtype, const char *segoverride) {
  1417.     const char *const *regs = big==2 ? regmmx : big ? is_32_op ? reg32 : reg16 : reg8;
  1418.     unsigned char modrm = *sptr++;
  1419.  
  1420.     ptr_insert_type = ptrtype;
  1421.  
  1422.     if (!is_32_addr) {
  1423.         strcpy(buf,"<<16-bit addr>>");
  1424.     } else {
  1425.         if ((modrm&7) == 4 && modrm<0xc0) {
  1426.             unsigned char sib = *sptr++;
  1427.             bool needplus = false;
  1428.  
  1429.             ptr_insert = buf;
  1430.  
  1431.             *buf++='[';
  1432.  
  1433.             // We have to watch out for these special cases:
  1434.             //
  1435.             //    MOD=00, SIB=x5 or xD    disp32[index]
  1436.             //    MOD=01,    SIB=x5 or xD    disp8[EBP+index]
  1437.             //    MOD=10, SIB=x5 or xD    disp32[EBP+index]
  1438.  
  1439.             // Print out base register; omit EBP for MOD=00
  1440.  
  1441.             if ((sib&7) != 5 || modrm>=0x40) {
  1442.                 strcpy(buf, reg32[sib&7]);
  1443.                 ADDRESS_ACCESS_32(sib&7);
  1444.                 buf+=3;
  1445.                 needplus = true;
  1446.             }
  1447.  
  1448.             // Print out index*scale; if index=100 there is no index register
  1449.  
  1450.             if ((sib&0x38)!=0x20) {
  1451.  
  1452.                 if (needplus)
  1453.                     *buf++ = '+';
  1454.  
  1455.                 strcpy(buf, reg32[(sib>>3)&7]);
  1456.                 ADDRESS_ACCESS_32((sib>>3)&7);
  1457.                 buf+=3;
  1458.  
  1459.                 if (sib>=0x40) {
  1460.                     *buf++ = '*';
  1461.                     *buf++ = '0' + (1<<((sib>>6)&3));
  1462.                 }
  1463.  
  1464.                 needplus = true;
  1465.             }
  1466.  
  1467.             // Print out displacement; force a disp32 for base=101, mod=00.
  1468.             // We can get only a disp32 if mod=00, base=101, and index=100,
  1469.             // so watch the plus
  1470.             
  1471.             if (modrm>=0x40 && modrm<0x80) {
  1472.                 buf+=sprintf(buf,"%+d",(int)(signed char)*sptr++);
  1473.             } else if (((sib&7) == 5 && modrm<0x40) || (modrm>=0x80 && modrm<0xc0)) {
  1474.                 buf+=sprintf(buf,"%s%08lx",needplus?"+":"",*(long *)sptr);
  1475.                 sptr+=4;
  1476.             }
  1477.  
  1478.             *buf++=']';
  1479.             *buf=0;
  1480.         } else switch(modrm & 0xc0) {
  1481.         case 0x00:
  1482.             ptr_insert = buf;
  1483.             if ((modrm & 7) == 5) {
  1484.                 sprintf(buf,"[0%08lxh]",*(long *)sptr);
  1485.                 sptr+=4;
  1486.             } else {
  1487.                 sprintf(buf,"[%s]",reg32[modrm&7]);
  1488.                 ADDRESS_ACCESS_32(modrm&7);
  1489.             }
  1490.             break;
  1491.         case 0x40:
  1492.             ptr_insert = buf;
  1493.             sprintf(buf,"[%s%+d]",reg32[modrm&7], (signed char)*sptr++);
  1494.             ADDRESS_ACCESS_32(modrm&7);
  1495.             break;
  1496.         case 0x80:
  1497.             ptr_insert = buf;
  1498.             sprintf(buf,"[%s+0%lxh]",reg32[modrm&7],*(long *)sptr);
  1499.             ADDRESS_ACCESS_32(modrm&7);
  1500.             sptr += 4;
  1501.             break;
  1502.         case 0xc0:
  1503.             strcpy(buf,regs[modrm&7]);
  1504.             DATA_ACCESS_32(modrm&7);
  1505.             break;
  1506.         }
  1507.     }
  1508.  
  1509.     while(*buf) ++buf;
  1510. }
  1511.  
  1512. static unsigned char *disasm_inst(unsigned char *sptr, unsigned char *sbase, char *buf, BOOL is_32) {
  1513.     unsigned char op;
  1514.     BOOL is_32_addr = is_32;
  1515.     BOOL is_32_op = is_32;
  1516.     const struct x86op *opdata;
  1517.     char *segment_override="";
  1518.     char *large_ptr_type, *ptr_ptr_type;
  1519.     long flags;
  1520.     const char *const *regx;
  1521.  
  1522.     unsigned char esave;
  1523.  
  1524.     regmask_modify = regmask_access = regmask_address=0;
  1525.     ptr_insert = NULL;
  1526.  
  1527.     for(;;) {
  1528.         op = *sptr++;
  1529.  
  1530.         // Special floating point handling for op=D8-DF, modrm>=0xc0
  1531.  
  1532.         if ((op&0xf8) == 0xd8 && *sptr >= 0xc0) {
  1533.             const char *opcode, *operand_format;
  1534.             unsigned char modrm = *sptr++;
  1535.  
  1536.             opcode = fpext_reg_tab[op-0xd8][(modrm - 0xc0)>>3][0];
  1537.             operand_format = fpext_reg_tab[op-0xd8][(modrm - 0xc0)>>3][1];
  1538.  
  1539.             if (opcode) {
  1540.                 buf += sprintf(buf, "%s\t", opcode);
  1541.                 buf += sprintf(buf, operand_format, modrm&7);
  1542.             } else {
  1543.                 if (operand_format)
  1544.                     for(int i=0; i<(modrm&7); i++)
  1545.                         while(*operand_format++);
  1546.  
  1547.                 if (!operand_format || !*operand_format)
  1548.                     buf += sprintf(buf, "db\t%02x,%02x", opcode, operand_format);
  1549.                 else
  1550.                     buf += sprintf(buf, operand_format);
  1551.             }
  1552.             break;
  1553.         }
  1554.  
  1555.  
  1556.         opdata = &singops[op];
  1557.  
  1558.         flags = opdata->flags;
  1559.  
  1560.         if (GETTYPE(flags) == TYPE_0f) {
  1561.             op = *sptr++;
  1562.             opdata = &prefix0f_ops[op];
  1563.             flags = opdata->flags;
  1564.         }
  1565.  
  1566.         if (flags == SPECIAL_3DNOW) {
  1567.             int i = 0;
  1568.  
  1569.             op = *sptr++;
  1570.  
  1571.             while(group_3DNow[i].opcode) {
  1572.                 if (group_3DNow[i].opcode == op) {
  1573.                     opdata = &group_3DNow[i].opdata;
  1574.                     flags = opdata->flags;
  1575.                     break;
  1576.                 }
  1577.                 ++i;
  1578.             }
  1579.         } else if (GETGROUP(flags)) {
  1580.             opdata = &groups[GETGROUP(flags)-1][(*sptr>>3)&7];
  1581.             flags |= opdata->flags;
  1582.         }
  1583.  
  1584.         PIPE_FORCE_U();        // Pentium: all prefixes except 0fh force u-pipe
  1585.  
  1586.         switch(GETTYPE(flags)) {
  1587.         case TYPE_cs_override:    segment_override = "cs:"; continue;
  1588.         case TYPE_ds_override:    segment_override = "ds:"; continue;
  1589.         case TYPE_ss_override:    segment_override = "ss:"; continue;
  1590.         case TYPE_es_override:    segment_override = "es:"; continue;
  1591.         case TYPE_fs_override:    segment_override = "fs:"; continue;
  1592.         case TYPE_gs_override:    segment_override = "gs:"; continue;
  1593.         case TYPE_operand_size_override: is_32_op = !is_32_op; continue;
  1594.         case TYPE_address_size_override: is_32_addr = !is_32_addr; continue;
  1595.         case TYPE_prefix:
  1596.             strcpy(buf, opdata->name);
  1597.             while(*buf) ++buf;
  1598.             *buf++=' ';
  1599.             continue;
  1600.         default:
  1601.             PIPE_RESET_UV();
  1602.             break;
  1603.         }
  1604.  
  1605.         if (opdata->name) {
  1606.             strcpy(buf, opdata->name);
  1607.             while(*buf) ++buf;
  1608.         }
  1609.  
  1610.         if (!is_32_op) switch(GETMOD(opdata->flags)) {
  1611.             case MOD16_take_d_off:
  1612.                 --buf;
  1613.                 break;
  1614.             case MOD16_d_to_w:
  1615.                 buf[-1] = 'w';
  1616.                 break;
  1617.             case MOD16_dq_to_wd:
  1618.                 buf[-2] = 'w';
  1619.                 buf[-1] = 'd';
  1620.                 break;
  1621.         }
  1622.  
  1623.         esave = sptr[0];
  1624.  
  1625.         regx = is_32_op ? reg32 : reg16;
  1626.         large_ptr_type = is_32_addr ? "dword ptr" : "word ptr";
  1627.         ptr_ptr_type = is_32_addr ? "fword ptr" : "dword ptr";
  1628.  
  1629.         for(int i=0; i<3; i++) {
  1630.             int amode = (flags>>(6*i)) & 63;
  1631.  
  1632.             if (!amode) continue;
  1633.  
  1634.             if (amode==ADDR_Idep) amode=op&1 ? ADDR_Iv : ADDR_Ib;
  1635.  
  1636.             if (i) *buf++=','; else *buf++='\t';
  1637.  
  1638.             switch(amode) {
  1639.             case ADDR_AL:    buf=strtack(buf,reg8[0]);            DATA_ACCESS_32(0);            break;
  1640.             case ADDR_CL:    buf=strtack(buf,reg8[1]);            DATA_ACCESS_32(1);            break;
  1641.             case ADDR_DX:    buf=strtack(buf,reg16[2]);            DATA_ACCESS_32(2);            break;
  1642.             case ADDR_EAX:    buf=strtack(buf,regx[0]);            DATA_ACCESS_32(0);            break;
  1643.             case ADDR_CS:    buf=strtack(buf,"cs");                DATA_ACCESS_SEGMENT(1);        break;
  1644.             case ADDR_DS:    buf=strtack(buf,"ds");                DATA_ACCESS_SEGMENT(3);        break;
  1645.             case ADDR_SS:    buf=strtack(buf,"ss");                DATA_ACCESS_SEGMENT(2);        break;
  1646.             case ADDR_ES:    buf=strtack(buf,"es");                DATA_ACCESS_SEGMENT(0);        break;
  1647.             case ADDR_FS:    buf=strtack(buf,"fs");                DATA_ACCESS_SEGMENT(4);        break;
  1648.             case ADDR_GS:    buf=strtack(buf,"gs");                DATA_ACCESS_SEGMENT(5);        break;
  1649.             case ADDR_1:    *buf++='1'; break;
  1650.             case ADDR_Ap:
  1651.                 if (is_32_addr) {
  1652.                     buf+=sprintf(buf,"%04x:%08lx",*(unsigned short *)(sptr+4), *(unsigned long *)sptr);
  1653.                     sptr += 6;
  1654.                 } else {
  1655.                     buf+=sprintf(buf,"%04x:%04x",*(unsigned short *)(sptr+2), *(unsigned short *)sptr);
  1656.                     sptr += 4;
  1657.                 }
  1658.                 break;
  1659.             case ADDR_Cd:    buf[0]='c'; buf[1]='r'; buf[2]='0'+((*sptr++)&7); break;
  1660.             case ADDR_Dd:    buf[0]='d'; buf[1]='r'; buf[2]='0'+((*sptr++)&7); break;
  1661.             case ADDR_Eb:    disasm_modrm(sptr, FALSE, buf, is_32_op, is_32_addr, "byte ptr ", segment_override);
  1662.                             break;
  1663.             case ADDR_Ep:    disasm_modrm(sptr, TRUE, buf, is_32_op, is_32_addr, ptr_ptr_type, segment_override);
  1664.                             break;
  1665.             case ADDR_Ev:    disasm_modrm(sptr, TRUE, buf, is_32_op, is_32_addr, large_ptr_type, segment_override);
  1666.                             break;
  1667.             case ADDR_Ew:    disasm_modrm(sptr, TRUE, buf, FALSE, is_32_addr, "word ptr ", segment_override);
  1668.                             break;
  1669.             case ADDR_Ed:    disasm_modrm(sptr, TRUE, buf, TRUE, is_32_addr, "dword ptr ", segment_override);
  1670.                             break;
  1671.             case ADDR_Eq:    disasm_modrm(sptr, TRUE, buf, TRUE, is_32_addr, "qword ptr ", segment_override);
  1672.                             break;
  1673.             case ADDR_Ex:    disasm_modrm(sptr, TRUE, buf, TRUE, is_32_addr, "tbyte ptr ", segment_override);
  1674.                             break;
  1675.             case ADDR_Gb:    buf=strtack(buf,reg8[(esave>>3)&7]);    DATA_ACCESS_32((esave>>3)&7);    break;
  1676.             case ADDR_Gv:    buf=strtack(buf,regx[(esave>>3)&7]);    DATA_ACCESS_32((esave>>3)&7);    break;
  1677.             case ADDR_Ib:    buf+=sprintf(buf,"%02x",*sptr++);
  1678.                             break;
  1679.             case ADDR_Ib2:    buf+=sprintf(buf,"%d",sptr[1]);
  1680.                             sptr += 2;
  1681.                             break;
  1682.             case ADDR_Ibs:    if (is_32_op) {
  1683.                                 buf+=sprintf(buf,"%08lx",(long)(signed char)*sptr++);
  1684.                             } else {
  1685.                                 buf+=sprintf(buf,"%04x",(unsigned short)(signed char)*sptr++);
  1686.                             }
  1687.                             break;
  1688.             case ADDR_Iv:    if (is_32_op) {
  1689.                                 buf+=sprintf(buf,"%08lx",*(long *)sptr);
  1690.                                 sptr+=4;
  1691.                                 break;
  1692.                             }
  1693.             case ADDR_Iw:    buf+=sprintf(buf,"%04x",*(unsigned short *)sptr);
  1694.                             sptr+=2;
  1695.                             break;
  1696.             case ADDR_Jb:    ++sptr;
  1697.                             if (is_32_addr)
  1698.                                 buf+=sprintf(buf,"%lx",(sptr-sbase) + (long)(signed char)sptr[-1]);
  1699.                             else
  1700.                                 buf+=sprintf(buf,"%x",(unsigned short)((sptr-sbase) + (long)(signed char)sptr[-1]));
  1701.                             break;
  1702.             case ADDR_Jv:    if (is_32_addr) {
  1703.                                 sptr += 4;
  1704.                                 buf+=sprintf(buf,"%lx",(sptr-sbase) + *(long *)(sptr-4));
  1705.                             } else {
  1706.                                 sptr += 2;
  1707.                                 buf+=sprintf(buf,"%x",(unsigned short)((sptr-sbase) + (long)*(signed short *)(sptr-2)));
  1708.                             }
  1709.                             break;
  1710.             case ADDR_M:    disasm_modrm(sptr, TRUE, buf, is_32_op, is_32_addr, "", segment_override);
  1711.                             break;
  1712.             case ADDR_Ma:    disasm_modrm(sptr, TRUE, buf, is_32_op, is_32_addr, large_ptr_type, segment_override);
  1713.                             break;
  1714.             case ADDR_Mp:    disasm_modrm(sptr, TRUE, buf, is_32_op, is_32_addr, ptr_ptr_type, segment_override);
  1715.                             break;
  1716.             case ADDR_Ob:    if (is_32_addr) {
  1717.                                 buf += sprintf(buf,"byte ptr [%08lx]",*(long *)sptr);
  1718.                                 sptr += 4;
  1719.                             } else {
  1720.                                 buf += sprintf(buf,"byte ptr [%04x]",*(unsigned short *)sptr);
  1721.                                 sptr += 2;
  1722.                             }
  1723.                             break;
  1724.             case ADDR_Ov:    if (is_32_addr) {
  1725.                                 buf += sprintf(buf,"%s [%08lx]",large_ptr_type,*(long *)sptr);
  1726.                                 sptr += 4;
  1727.                             } else {
  1728.                                 buf += sprintf(buf,"%s [%04x]",large_ptr_type,*(unsigned short *)sptr);
  1729.                                 sptr += 2;
  1730.                             }
  1731.                             break;
  1732.             case ADDR_Pd:    // fall through
  1733.             case ADDR_Pq:    buf[0]='m'; buf[1]='m'; buf[2]='0'+((esave>>3)&7); buf += 3; DATA_ACCESS_MMX((esave>>3)&7);
  1734.                 break;
  1735.             case ADDR_Pq2:    buf[0]='m'; buf[1]='m'; buf[2]='0'+(*sptr&7); buf += 3; DATA_ACCESS_MMX(*sptr&7);
  1736.                 break;
  1737.             case ADDR_Qd:    // fall through
  1738.             case ADDR_Qq:    disasm_modrm(sptr, 2, buf, is_32_op, is_32_addr, "", segment_override);
  1739.                             break;
  1740.             case ADDR_Rd:    buf = strtack(buf, reg32[*sptr++ & 7]);                DATA_ACCESS_32(sptr[-1]&7);        break;
  1741.             case ADDR_Sw:    buf = strtack(buf, sregs[(esave>>3)&7]); break;
  1742.             case ADDR_Xb:    buf+=sprintf(buf,"%sbyte ptr [%s]",segment_override,regx[6]);            DATA_ACCESS_32(6);    break;
  1743.             case ADDR_Xv:    buf+=sprintf(buf,"%s%s [%s]",segment_override,large_ptr_type,regx[6]);    DATA_ACCESS_32(6);    break;
  1744.             case ADDR_Yb:    buf+=sprintf(buf,"%sbyte ptr [%s]",segment_override,regx[7]);            DATA_ACCESS_32(7);    break;
  1745.             case ADDR_Yv:    buf+=sprintf(buf,"%s%s [%s]",segment_override,large_ptr_type,regx[7]);    DATA_ACCESS_32(7);    break;
  1746.  
  1747.             case ADDR_reg8:    buf = strtack(buf, reg8[op&7]);                        DATA_ACCESS_32(op&7);            break;
  1748.             case ADDR_reg32: buf = strtack(buf, regx[op&7]);                    DATA_ACCESS_32(op&7);            break;
  1749.             }
  1750.  
  1751.             if (!i) {
  1752.                 regmask_modify = regmask_access;
  1753.                 regmask_access = 0;
  1754.             }
  1755.  
  1756.         }
  1757.  
  1758.         break;
  1759.     }
  1760.     buf[0]=0;
  1761.  
  1762.     if (!((regmask_modify|regmask_access) & 0xff) && ptr_insert) {
  1763.         memmove(ptr_insert + strlen(ptr_insert_type), ptr_insert, strlen(ptr_insert)+1);
  1764.         memcpy(ptr_insert, ptr_insert_type, strlen(ptr_insert_type));
  1765.     }
  1766.  
  1767.     return sptr;
  1768. }
  1769.  
  1770. /////////////////////////////////////////////////////////////////////////
  1771.  
  1772. #define PENALTY_RAW            (0x00000001L)
  1773. #define PENALTY_WAW            (0x00000002L)
  1774. #define PENALTY_AGI            (0x00000004L)
  1775.  
  1776. void CodeDisassemblyWindow::parse() {
  1777.     unsigned char *ip = (unsigned char *)code, *ip_start;
  1778.     unsigned char *ipend = ip + length;
  1779.     lbent *ipd = lbents, *ipd_last = NULL;
  1780.     long regmask_last_clock_modify = 0;
  1781.     long regmask_last_inst_modify = 0;
  1782.     long penalty_flags;
  1783.     int    cnt=0;
  1784.  
  1785.     if (!ipd) {
  1786.         num_ents = 0;
  1787.         return;
  1788.     }
  1789.  
  1790.     while(ip < ipend && cnt++<MAX_INSTRUCTIONS) {
  1791.         ip_start = ip;
  1792.  
  1793.         ip = disasm_inst(ip, (unsigned char *)code, buf, TRUE);
  1794.  
  1795.         // penalties?
  1796.  
  1797.         penalty_flags = 0;
  1798.  
  1799.         if (regmask_last_clock_modify & regmask_address)
  1800.             penalty_flags |= PENALTY_AGI;
  1801.  
  1802.         if (ipd_last && pipe_force!=PIPE_U) {
  1803.             if (regmask_last_inst_modify & regmask_address)
  1804.                 penalty_flags |= PENALTY_AGI | PENALTY_RAW;
  1805.  
  1806.             if (regmask_last_inst_modify & regmask_access)
  1807.                 penalty_flags |= PENALTY_RAW;
  1808.  
  1809.             if (regmask_last_inst_modify & regmask_modify)
  1810.                 penalty_flags |= PENALTY_WAW;
  1811.         }
  1812.  
  1813.         // pairable in V-pipe?
  1814.  
  1815.         if (ipd_last && pipe_force!=PIPE_U && !(penalty_flags & (PENALTY_RAW | PENALTY_WAW))) {
  1816.  
  1817.             ipd_last->ip_v = ip_start;
  1818.             ipd_last->flags |= penalty_flags;
  1819.             ipd_last = NULL;
  1820.  
  1821.             regmask_last_clock_modify |= regmask_modify;
  1822.  
  1823.         } else {
  1824.  
  1825.             // pairable in U-pipe?
  1826.  
  1827.             if (pipe_force != PIPE_V) {
  1828.                 ipd->ip_u = ip_start;
  1829.                 ipd->ip_v = NULL;
  1830.                 ipd_last = ipd;
  1831.                 regmask_last_inst_modify = regmask_modify;
  1832.             } else {
  1833.                 ipd->ip_u = NULL;
  1834.                 ipd->ip_v = ip_start;
  1835.                 ipd_last = NULL;
  1836.                 regmask_last_inst_modify = 0;
  1837.             }
  1838.             ipd->flags = penalty_flags;
  1839.  
  1840.             ++ipd;
  1841.  
  1842.             regmask_last_clock_modify = regmask_modify;
  1843.         }
  1844.     }
  1845.  
  1846.     num_ents = ipd-lbents;
  1847. }
  1848.  
  1849. char *CodeDisassemblyWindow::penalty_string(long f) {
  1850.     char *bp = buf;
  1851.  
  1852.     if (f & PENALTY_RAW)
  1853.         bp = strtack(bp, "RAW");
  1854.  
  1855.     if (f & PENALTY_WAW) {
  1856.         if (bp>buf) bp=strtack(bp,", ");
  1857.         bp = strtack(bp, "WAW");
  1858.     }
  1859.  
  1860.     if (f & PENALTY_AGI) {
  1861.         if (bp>buf) bp=strtack(bp,", ");
  1862.         bp = strtack(bp, "AGI");
  1863.     }
  1864.  
  1865.     *bp=0;
  1866.  
  1867.     return buf;
  1868. }
  1869.  
  1870. BOOL CodeDisassemblyWindow::post(HWND hWnd) {
  1871.     if (!lbents) return FALSE;
  1872.  
  1873.     DialogBoxParam(g_hInst, MAKEINTRESOURCE(IDD_DISASM), hWnd, CodeDisassemblyWindow::DlgProc, (LPARAM)this);
  1874.  
  1875.     return TRUE;
  1876. }
  1877.  
  1878. long CodeDisassemblyWindow::getInstruction(char *buf, long val) {
  1879.     lbent *ipd;
  1880.     unsigned char *ip;
  1881.  
  1882.     if ((val>>1) >= num_ents)
  1883.         return 0;
  1884.  
  1885.     ipd = &lbents[val>>1];
  1886.     ip = val&1 ? ipd->ip_v : ipd->ip_u;
  1887.  
  1888.     if (!ip) {
  1889.         val |= 1;
  1890.         ip = ipd->ip_v;
  1891.     }
  1892.  
  1893.     wsprintf(buf, "%08lx: ", ip - (unsigned char *)code + (unsigned char *)abase);
  1894.     disasm_inst(ip, (unsigned char *)rbase, buf+10, TRUE);
  1895.  
  1896.     if (ip - (unsigned char *)code + (unsigned char *)abase == pFault)
  1897.         strcat(buf, "      <-- FAULT");
  1898.  
  1899.     ++val;
  1900.  
  1901.     if (val&1 && !ipd->ip_v)
  1902.         ++val;
  1903.  
  1904.     return val;
  1905. }
  1906.  
  1907. void CodeDisassemblyWindow::DoInitListbox(HWND hwndList) {
  1908.     SendMessage(hwndList, LB_SETCOUNT, num_ents, 0);
  1909.  
  1910.     if (hFontMono)
  1911.         SendMessage(hwndList, WM_SETFONT, (WPARAM)hFontMono, MAKELPARAM(TRUE, 0));
  1912. }
  1913.  
  1914. BOOL CodeDisassemblyWindow::DoMeasureItem(LPARAM lParam) {
  1915.     if (((LPMEASUREITEMSTRUCT)lParam)->CtlType != ODT_LISTBOX) return FALSE;
  1916.     ((LPMEASUREITEMSTRUCT)lParam)->itemHeight = 23;
  1917.     return TRUE;
  1918. }
  1919.  
  1920. BOOL CodeDisassemblyWindow::DoDrawItem(LPARAM lParam) {
  1921.     LPDRAWITEMSTRUCT lpdis = (LPDRAWITEMSTRUCT)lParam;
  1922.     lbent *ipd;
  1923.     HBRUSH hbrBack;
  1924.     HPEN hPenOld;
  1925.  
  1926.     if (lpdis->CtlType != ODT_LISTBOX) return FALSE;
  1927.     if (!(lpdis->itemAction & ODA_DRAWENTIRE)) return FALSE;
  1928.     if (lpdis->itemID < 0) return FALSE;
  1929.  
  1930. //    ipd = (lbent *)lpdis->itemData;
  1931.     ipd = &lbents[lpdis->itemID];
  1932.  
  1933.     if (hbrBack = CreateSolidBrush(RGB(0xe8,0xff,0xe8))) {
  1934.         RECT r;
  1935.  
  1936.         r.left = lpdis->rcItem.left;
  1937.         r.top = lpdis->rcItem.top+11;
  1938.         r.right = lpdis->rcItem.right;
  1939.         r.bottom = lpdis->rcItem.bottom;
  1940.  
  1941.         FillRect(lpdis->hDC, &r, hbrBack);
  1942.         DeleteObject(hbrBack);
  1943.     }
  1944.     if (hbrBack = CreateSolidBrush(RGB(0xe8,0xe8,0xff))) {
  1945.         RECT r;
  1946.  
  1947.         r.left = lpdis->rcItem.left;
  1948.         r.top = lpdis->rcItem.top;
  1949.         r.right = lpdis->rcItem.right;
  1950.         r.bottom = lpdis->rcItem.top+11;
  1951.  
  1952.         FillRect(lpdis->hDC, &r, hbrBack);
  1953.  
  1954.         DeleteObject(hbrBack);
  1955.     }
  1956.  
  1957.     SetBkMode(lpdis->hDC, TRANSPARENT);
  1958.     SetTextColor(lpdis->hDC, RGB(0x00,0x00,0x00));
  1959.  
  1960.     if (ipd->ip_u) {
  1961.         wsprintf(buf, "%08lx: ", ipd->ip_u - (unsigned char *)code + (unsigned char *)abase);
  1962.         disasm_inst(ipd->ip_u, (unsigned char *)rbase, buf+10, TRUE);
  1963.  
  1964.         TabbedTextOut(    lpdis->hDC,
  1965.                         lpdis->rcItem.left,
  1966.                         lpdis->rcItem.top,
  1967.                         buf,
  1968.                         strlen(buf),
  1969.                         0,
  1970.                         NULL,
  1971.                         0
  1972.                         );
  1973.  
  1974.     }
  1975.  
  1976.     if (ipd->flags) {
  1977.         penalty_string(ipd->flags);                
  1978.         TextOut(lpdis->hDC,
  1979.                 (lpdis->rcItem.left+3*lpdis->rcItem.right)/4,
  1980.                 lpdis->rcItem.top+2,
  1981.                 buf,
  1982.                 strlen(buf)
  1983.                 );
  1984.     }
  1985. //            SetTextColor(lpdis->hDC, RGB(0x80,0x00,0x00));
  1986.  
  1987.     if (ipd->ip_v) {
  1988.         wsprintf(buf, "%08lx: ", ipd->ip_v - (unsigned char *)code + (unsigned char *)abase);
  1989.         disasm_inst(ipd->ip_v, (unsigned char *)rbase, buf+10, TRUE);
  1990.  
  1991.         TabbedTextOut(    lpdis->hDC,
  1992.                         lpdis->rcItem.left,
  1993.                         lpdis->rcItem.top+11,
  1994.                         buf,
  1995.                         strlen(buf),
  1996.                         0,
  1997.                         NULL,
  1998.                         0
  1999.                         );
  2000.     }
  2001.  
  2002.     hPenOld = (HPEN)SelectObject(lpdis->hDC, GetStockObject(BLACK_PEN));
  2003.     MoveToEx(lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.bottom-1, NULL);
  2004.     LineTo(lpdis->hDC, lpdis->rcItem.right, lpdis->rcItem.bottom-1);
  2005.     DeleteObject(SelectObject(lpdis->hDC, hPenOld));
  2006.  
  2007.     return TRUE;
  2008. }
  2009.  
  2010. BOOL CALLBACK CodeDisassemblyWindow::DlgProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) {
  2011.     CodeDisassemblyWindow *thisPtr = (CodeDisassemblyWindow *)GetWindowLong(hDlg, DWL_USER);
  2012.  
  2013.     switch(msg) {
  2014.  
  2015.         case WM_INITDIALOG:
  2016.             SetWindowLong(hDlg, DWL_USER, lParam);
  2017.             thisPtr = (CodeDisassemblyWindow *)lParam;
  2018.  
  2019.             thisPtr->DoInitListbox(GetDlgItem(hDlg, IDC_ASMBOX));
  2020.             return TRUE;
  2021.  
  2022.         case WM_COMMAND:
  2023.             switch(LOWORD(wParam)) {
  2024.             case IDCANCEL: case IDOK:
  2025.                     EndDialog(hDlg, FALSE);
  2026.                     return TRUE;
  2027.             }
  2028.             break;
  2029.  
  2030.         case WM_MEASUREITEM:
  2031.             return thisPtr->DoMeasureItem(lParam);
  2032.  
  2033.         case WM_DRAWITEM:
  2034.             return thisPtr->DoDrawItem(lParam);
  2035.     }
  2036.  
  2037.     return FALSE;
  2038. }
  2039.